內(nèi)容純屬個(gè)人理解,不對(duì)之處,歡迎指正。
多裝飾器示例
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()
運(yùn)行結(jié)果:
---deco2---
---deco1---
---start---
---wrapper1:before func---
---wrapper2:before func---
---foo---
---wrapper2:after func---
---wrapper1:after func---
通過(guò)現(xiàn)象看本質(zhì)。我們注意到,程序開(kāi)始執(zhí)行后,裝飾函數(shù)是最先開(kāi)始執(zhí)行的,然后再執(zhí)行的foo。原因就是Python解釋器在執(zhí)行到foo定義處時(shí),檢測(cè)到有兩個(gè)裝飾器,所以立即執(zhí)行其中的裝飾代碼對(duì)函數(shù)進(jìn)行裝飾,此時(shí)foo函數(shù)便具有了額外的功能。
接下來(lái)在執(zhí)行foo時(shí)可以看到:多裝飾器的裝飾順序是由內(nèi)到外,而執(zhí)行順序是由外到內(nèi)。
多裝飾過(guò)程拆分
fn2 = deco2(foo) # ---deco2---
fn1 = deco1(fn2) # ---deco1---
foo = fn1
print(foo) # <function deco1.<locals>.wrapper1 at 0x7f18baf4e620>
foo函數(shù)作為參數(shù)傳遞到deco2,deco2執(zhí)行;然后將結(jié)果作為參數(shù)傳遞到deco1,deco1執(zhí)行;然后將結(jié)果賦值給foo,此時(shí)的foo即為裝飾后的函數(shù)wrapper1,如果想保留原函數(shù)相關(guān)信息,可以使用functools中的wraps函數(shù)。