内容纯属个人理解,不对之处,欢迎指正。
多装饰器示例
def deco1(func):
'''i am deco1'''
print('---deco1---')
def wrapper1(*args, **kwargs):
'''i am wrapper1'''
print('---wrapper1:before func---')
func(*args, **kwargs)
print('---wrapper1:after func---')
return wrapper1
def deco2(func):
'''i am deco2'''
print('---deco2---')
def wrapper2(*args, **kwargs):
'''i am wrapper2'''
print('---wrapper2:before func---')
func(*args, **kwargs)
print('---wrapper2:after func---')
return wrapper2
@deco1
@deco2
def foo():
'''i am foo'''
print('---foo---')
if __name__ == '__main__':
print('---start---')
foo()
运行结果:
---deco2---
---deco1---
---start---
---wrapper1:before func---
---wrapper2:before func---
---foo---
---wrapper2:after func---
---wrapper1:after func---
通过现象看本质。我们注意到,程序开始执行后,装饰函数是最先开始执行的,然后再执行的foo。原因就是Python解释器在执行到foo定义处时,检测到有两个装饰器,所以立即执行其中的装饰代码对函数进行装饰,此时foo函数便具有了额外的功能。
接下来在执行foo时可以看到:多装饰器的装饰顺序是由内到外,而执行顺序是由外到内。
多装饰过程拆分
fn2 = deco2(foo) # ---deco2---
fn1 = deco1(fn2) # ---deco1---
foo = fn1
print(foo) # <function deco1.<locals>.wrapper1 at 0x7f18baf4e620>
foo函数作为参数传递到deco2,deco2执行;然后将结果作为参数传递到deco1,deco1执行;然后将结果赋值给foo,此时的foo即为装饰后的函数wrapper1,如果想保留原函数相关信息,可以使用functools中的wraps函数。
网友评论