裝飾器
?????為了動態(tài)拓展函數(shù),而不去破壞原函數(shù)的調(diào)用,產(chǎn)生了裝飾器。通常使用裝飾器給函數(shù)加log。
單層裝飾器
def trim(f):
def inner(*args,**kwargs):
print("1"*10)
ret = f(*args,**kwargs)
print("1"*10)
return ret
return inner
"""
@trim : func = trim(func)
"""
@trim
def func(*args,**kwargs):
for i,j in enumerate(*args):
print(i,j)
print(kwargs)
return args
if __name__ == '__main__':
func([1,3],name="hhh")

單層裝飾器.png
?????以上是一個(gè)單層裝飾器,trim是裝飾函數(shù),func是被裝飾函數(shù)。@trim是Python中的一顆語法糖,它等價(jià)于func = trim(func)。

執(zhí)行過程.png
?????使用func.__name__查看func的名字可以發(fā)現(xiàn)它其實(shí)是inner。
tips:
- 如果被裝飾函數(shù)沒有參數(shù) ,inner也可以不用帶參數(shù),但是如果被裝飾函數(shù)有了參數(shù),inner函數(shù)必須帶有參數(shù),因?yàn)樵趇nner函數(shù)中調(diào)用func時(shí),必須要有參數(shù),這時(shí)的參數(shù)只能來自于inner。一般來說,無論被裝飾函數(shù)有沒有參數(shù),我們都會給inner兩個(gè)參數(shù),一個(gè)可變參數(shù),一個(gè)關(guān)鍵字參數(shù)。
- 同樣如果被裝飾函數(shù)有返回值,需要在inner中調(diào)用func進(jìn)行保存,然后在inner中返回這個(gè)值
多層裝飾器
def trim(f):
def inner(*args,**kwargs):
print("1"*10)
ret = f(*args,**kwargs)
print("1"*10)
return ret
return inner
def wrap(f):
def wahia(*args,**kwargs):
print("2"*10)
ret = f(*args,**kwargs)
print("2"*10)
return ret
return wahia
"""
@wrap : func = wrap(func)
@trim : func = trim(func)
"""
@wrap
@trim
def func(*args,**kwargs):
for i,j in enumerate(*args):
print(i,j)
print(kwargs)
return args
if __name__ == '__main__':
func([1,3],name="hhh")
# print(func.__name__)

多層裝飾器.png
?????多層裝飾器的時(shí)候,要注意位置,位置不同所產(chǎn)生的結(jié)果也會不同。以上是func先被trim裝飾,返回inner,此時(shí)func = inner,在此之上再被wrap裝飾,返回wahia。所以func.__name__是wahia。