需求
python创建一个装饰器通常会有内函数与外函数,即下边代码中的inner和outter函数
当多层装饰时,装饰器加载及执行顺序,有时候会搞混。
为了彻底搞明白并且能够记住,编写本文。
先放结论:
- 装饰器加载时,从下往上(越接近原函数,越先装饰),加载时执行的是外函数,即outter
- 具体执行时,从上往下,执行的是内函数,即inner
形象点理解,原函数是个手机,装饰器加载就相当于给手机打包裹,加载多个装饰器,就是打了多层包裹,那么最先打包时产生的行为就要先执行。反过来拿到包裹要拆开,就要从外向内一层层拆,越在外的装饰器就要越先拆掉(执行)。以上就形象的描述装饰器与原函数的远近关系,从而方便记忆加载和执行顺序。
代码
def outter1(func1): # func1实际就是inner2
print('加载了outter1')
def inner1(*args, **kwargs):
print('执行了inner1')
r1 = func1(*args, **kwargs)
return r1
return inner1
def outter2(func2): # func2实际就是inner3
print('加载了outter2')
def inner2(*args, **kwargs):
print('执行了inner2')
res2 = func2(*args, **kwargs)
return res2
return inner2
def outter3(func3): # func3实际就是index
print('加载了outter3')
def inner3(*args, **kwargs):
print('执行了inner3')
res3 = func3(*args, **kwargs)
return res3
return inner3
@outter1 # outter1(inner2的内存地址) 返回 inner1对象
@outter2 # outter2(inner3的内存地址) 返回 inner2对象
@outter3 # outter3(原函数index对象) 返回 inner3对象
def index():
print('from index')
# 执行index时,就是拆包裹的过程。代码执行到此时,装饰器加载已经完成(即outter函数已经全部执行了),接下来要执行的都是inner函数
print("即将执行index===================")
index()
结果
输出结果如下:
加载了outter3
加载了outter2
加载了outter1
即将执行index===================
执行了inner1
执行了inner2
执行了inner3
from index