Loading

多层装饰器叠加装饰

多层装饰器叠加

加载顺序自下而上,执行顺序自上而下。

def wrapper1(func1):  # func1的内存地址是inner2
    print('from func1',func1)
    def inner1(*args,**kwargs):
        print('这是inner1.被装饰函数执行前')
        res1 = func1(*args,**kwargs)
        print('这是inner1.被装饰函数执行后')
        return res1
    return inner1

def wrapper2(func2):  # func2的内存地址是inner3
    print('from func2',func2)
    def inner2(*args,**kwargs):
        print('inner2,被装饰函数执行前')
        res2 = func2(*args,**kwargs)
        print('inner2,被装饰函数执行后')
        return res2
    return inner2

def wrapper3(func3):  # func3 的内存地址是total
    print('from func3',func3)
    def inner3(*args,**kwargs):
        print('inner3,被装饰函数执行前')
        res3 = func3(*args,**kwargs)
        print('inner3,被装饰函数执行后')
        return res3
    return inner3

@wrapper1  # wrapper2 = wrapper1(wrapper2) = inner1的内存地址
@wrapper2  # wrapper3 = wrapper2(wrapper3) = inner2的内存地址
@wrapper3  # total = wrapper3(total) = inner3的内存地址
def total(a, b):
    print(a+b)
    return a+b

上述叠加多个装饰器的语义本质其实就是:

total = wrapper1(wrapper2(wrapper3(total)))

不调用被装饰函数的执行结果:

from func3 <function total at 0x0000000002798790>
from func2 <function wrapper3.<locals>.inner3 at 0x0000000002798820>
from func1 <function wrapper2.<locals>.inner2 at 0x00000000027988B0>

@wrapper3等于wrapper(total),加括号会直接调用该函数,所以装饰器的第一层代码会执行。

调用结果:

total()

from func3 <function total at 0x0000000002788790>
from func2 <function wrapper3.<locals>.inner3 at 0x0000000002788820>
from func1 <function wrapper2.<locals>.inner2 at 0x00000000027888B0>
这是inner1.被装饰函数执行前
这是inner2,被装饰函数执行前
这是inner3,被装饰函数执行前
这里是原total
这是inner3,被装饰函数执行后
这是inner2,被装饰函数执行后
这是inner1.被装饰函数执行后
posted @ 2020-07-31 10:32  吃了好多肉  阅读(145)  评论(0编辑  收藏  举报