一、叠加多个装饰器
加载顺序:自下而上
运行顺序:自上而下
代码:
def deco1(func1): #func1=wrapper2的内存地址 print('装饰器1') def wrapper1(*args,**kwargs): print('wrapper1===>') res1=func1(*args,**kwargs) return res1 return wrapper1 def deco2(func2): #func2= wrapper3的内存地址 print('装饰器2') def wrapper2(*args,**kwargs): print('wrapper2===>') res2=func2(*args,**kwargs) return res2 return wrapper2 def deco3(func3): #func3=最原始的那个被装饰函数的内存地址 print('装饰器3') def wrapper3(*args,**kwargs): print('wrapper3===>') res3=func3(*args,**kwargs) return res3 return wrapper3 @deco1 #deco1(wrapper2的内存地址)=》wrapper1的内存地址 @deco2 #deco2(wrapper3的内存地址)=》wrapper2的内存地址 @deco3 #deco3(最原始的那个被装饰函数的内存地址)=》wrapper3的内存地址 def index(x,y): print('index==>',x,y)
index(1,2)
运行结果
装饰器3 装饰器2 装饰器1 wrapper1===> wrapper2===> wrapper3===> index==> 1 2
那么为什么会是这样的顺序???
看到这个执行结果,我们可能会疑惑,为什么先打印了装饰器3,装饰器2,装饰器1呢?
我们去掉函数执行,只留下函数的定义,代码如下:
def deco1(func1): #func1=wrapper2的内存地址 print('装饰器1') def wrapper1(*args,**kwargs): print('wrapper1===>') res1=func1(*args,**kwargs) return res1 return wrapper1 def deco2(func2): #func2= wrapper3的内存地址 print('装饰器2') def wrapper2(*args,**kwargs): print('wrapper2===>') res2=func2(*args,**kwargs) return res2 return wrapper2 def deco3(func3): #func3=最原始的那个被装饰函数的内存地址 print('装饰器3') def wrapper3(*args,**kwargs): print('wrapper3===>') res3=func3(*args,**kwargs) return res3 return wrapper3 @deco1 #deco1(wrapper2的内存地址)=》wrapper1的内存地址 @deco2 #deco2(wrapper3的内存地址)=》wrapper2的内存地址 @deco3 #deco3(最原始的那个被装饰函数的内存地址)=》wrapper3的内存地址 def index(x,y): print('index==>',x,y)
执行结果:
装饰器3
装饰器2
装饰器1
也就是说在index方法没有执行的时候,装饰器函数就执行了
此处我们需要先弄清楚,函数和函数调用的区别,index是一个函数,它的值是函数本身,index()是函数的调用,它的值是函数的执行结果。
在被装饰器函数定义阶段,也就是函数调用之前
@deco1 #deco1(wrapper2的内存地址)=》wrapper1的内存地址 @deco2 #deco2(wrapper3的内存地址)=》wrapper2的内存地址 @deco3 #deco3(最原始的那个被装饰函数的内存地址)=》wrapper3的内存地址 def index(x,y): print('index==>',x,y)
这段代码相当于:
deco1(deco2(deco3(index)))
deco1和deco2和deco3的返回值都是一个函数,所以deco1(deco2(deco3(index)))也是一个函数,deco1包含了deco2,deco2包含了deco3
index(1,3)相当于deco1(deco2(deco3(index)))()
所以index()在执行时,deco3--》deco2--》deco1--》deco1--》deco2--》deco3--》index--》deco3--》deco2--》deco1按照这样的顺序执行