美文网首页
python --@函数装饰器详解

python --@函数装饰器详解

作者: 有事没事扯扯淡 | 来源:发表于2019-08-01 16:52 被阅读0次

    当程序使用“@函数”(比如函数 A)装饰另一个函数(比如函数 B)时,实际上完成如下两步:

    将被修饰的函数(函数 B)作为参数传给 @ 符号引用的函数(函数 A)
    将函数 B 替换(装饰)成第 1 步的返回值。

    举个栗子~~~

    def funA(fn):
        print('A')
        fn() # 执行传入的fn参数
        return 'fkit'
    '''
    下面装饰效果相当于:funA(funB),
    funB 将会替换(装饰)成 funA() 语句的返回值;
    由于funA()函数返回 fkit,因此 funB 就是 fkit
    '''
    @funA
    def funB():
        print('B')
    print(funB) # fkit
    

    上面程序使用 @funA 修饰 funB,这意味着程序要完成两步操作:

    • 将 funB 作为 funA() 的参数,也就是上面代码中 @funA 相当于执行 funA(funB)。
    • 将 funB 替换成 funA() 执行的结果,funA() 执行完成后返回 fkit,因此 funB 就不再是函数,而是被替换成一个字符串。
      运行上面程序,可以看到如下输出结果:
    A
    B
    fkit
    

    被修饰的函数总是被替换成 @ 符号所引用的函数的返回值,因此被修饰的函数会变成什么,完全由于 @ 符号所引用的函数的返回值决定,换句话说,如果 @ 符号所引用的函数的返回值是函数,那么被修饰的函数在替换之后还是函数。

    def foo(fn):
        # 定义一个嵌套函数
        def bar(*args):
            print("===1===", args)
            n = args[0]
            print("===2===", n * (n - 1))
            # 查看传给foo函数的fn函数
            print(fn.__name__)
            fn(n * (n - 1))
            print("*" * 15)
            return fn(n * (n - 1))
        return bar
    '''
    下面装饰效果相当于:foo(my_test),
    my_test将会替换(装饰)成该语句的返回值;
    由于foo()函数返回bar函数,因此funB就是bar
    '''
    @foo
    def my_test(a):
        print("==my_test函数==", a)
    # 打印my_test函数,将看到实际上是bar函数
    print(my_test) # <function foo.<locals>.bar at 0x00000000021FABF8>
    # 下面代码看上去是调用my_test(),其实是调用bar()函数
    my_test(10)
    my_test(6, 5)
    

    运行上面程序,可以看到如下输出结果:

    <function foo.<locals>.bar at 0x000001C2A5953510>
    ===1=== (10,)
    ===2=== 90
    my_test
    ==my_test函数== 90
    ***************
    ==my_test函数== 90
    ===1=== (6, 5)
    ===2=== 30
    my_test
    ==my_test函数== 30
    ***************
    ==my_test函数== 30
    

    [参考链接]
    http://c.biancheng.net/view/2270.html

    相关文章

      网友评论

          本文标题:python --@函数装饰器详解

          本文链接:https://www.haomeiwen.com/subject/pxdcdctx.html