当某个函数加载了多个装饰器的时候,比如说:
def x1(func):
print("x1_1")
def newFunc():
print("x1_2")
func()
print("x1_3")
print("x1_4")
return newFunc
def x2(func):
print("x2_1")
def newFunc():
print("x2_2")
func()
print("x2_3")
print("x2_4")
return newFunc
@x1
@x2
def x():
print("x")
其效果为:
从上述定义和执行情况可以看出,当一个函数在定义的时候被装载了多个装饰器的时候,定义时其装饰器的内部代码是先x2,再x1,即靠近被定义函数的装饰器代码先执行,远离被定义函数的装饰器代码后执行。
在函数执行的时候,其执行的是装饰器所返回的wrapper,此wrapper中执行被定义函数加一些附加操作,那么在wrapper之中,被定义函数执行之前的代码的执行顺序,先x1,后x2,也就是远离被定义函数的装饰器内部定义的wrapper中被定义函数之前的代码先执行,靠近的后执行。而对于wrapper中被定义函数执行之后的代码的执行顺序,则和定义时的执行顺序相同。(好吧,这里可能说的有点晕,不过结合代码和图片应该能够很好的理解)
可以近似理解为一种压栈出栈的操作,在加载装饰器的时候,从靠近函数的装饰器开始压栈(开始装载),在实际调用函数的时候,再按反顺序出栈,以达到在调用装饰器所返回的wrapper中,被定义函数执行之前的时候,其内部的代码能够按照写代码的顺序(即从上往下)执行。