多层装饰器叠加
加载顺序自下而上,执行顺序自上而下。
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.被装饰函数执行后