装饰器函数的执行顺序是分为(被装饰函数)定义阶段和(被装饰函数)执行阶段的,装饰器函数在被装饰函数定义好后立即执行
- 在函数定义阶段:执行顺序是从最靠近函数的装饰器开始,自内而外的执行
- 在函数执行阶段:执行顺序由外而内,一层层执行
代码如下:
-
def war1(func):
-
print("war1")
-
def inner(*args, **kwargs):
-
print("======war1 start=====")
-
func(*args, **kwargs) #inner
-
print("======war1 end=====")
-
return inner
-
def war2(func):
-
print("war2")
-
def inner(*args,**kwargs):
-
print("======war2 start=====")
-
func(*args,**kwargs)
-
print("======war2 end=====")
-
return inner
-
@war1
-
@war2
-
def f():
-
print("****self****")
-
f()
执行结果:
那么为什么会是这样的顺序
看到这个执行结果,我们可能会疑惑,为什么先打印了war2 和war1呢?
首先要知道,装饰器函数在被装饰函数定义好后就立即执行了
我们去掉函数执行,只留下函数的定义,代码如下:
-
def war1(func):
-
print("war1")
-
def inner(*args, **kwargs):
-
print("======war1 start=====")
-
func(*args, **kwargs) #inner
-
print("======war1 end=====")
-
return inner
-
def war2(func):
-
print("war2")
-
def inner(*args,**kwargs):
-
print("======war2 start=====")
-
func(*args,**kwargs)
-
print("======war2 end=====")
-
return inner
-
@war1
-
@war2
-
def f():
-
print("****self****")
执行结果:
也就是说在 f 方法没有执行的时候,装饰器函数就执行了
此处我们需要先弄清楚,函数和函数调用的区别,f 是一个函数,它的值是函数本身, f( )是函数的调用,它的值是函数的执行结果
在被装饰函数定义阶段,也就是函数调用之前:
-
@war1
-
@war2
-
def f():
-
print("****self****")
这段代码相当于:
war1(war2(f))
war1和war2的返回值都是一个函数,所以war1(war2(f))也是一个函数,war2包含了f函数,war1包含了war2
f() 相当于 war1(war2(f))()
所以f ( )在执行时,war2-->war1--> war1-->war2-->f -->war2-->war1 按照这样的顺序执行
图画的有点丑,见谅。
原文转载至:https://blog.youkuaiyun.com/u013411246/article/details/80571462