def wrapper(fn): # fn是目標函數 def inner(*args, **kwargs): # 聚合 爲目標函數傳參,無敵傳參,接收到的是元組 # 在執行目標函數以前 ret = fn(*args, **kwargs) # 接收到的全部參數,打散傳遞給正常參數, 調用目標函數,ret是目標函數的返回值 # 在執行目標函數以後 return ret # 把目標函數返回值返回,保證函數正常運行 return inner @wrapper # target_func = wrapper(target_func) # 此時fn就是target_func def target_func(): pass target_func() # 此時執行的是inner()
二、帶有參數的裝飾器 python
def wrapper_out(flag): # 裝飾器自己的參數 def wrapper(fn): # 目標函數 def inner(*args, **kwargs): # 目標函數執行須要的參數 if flag == True: print('看看天氣預報,知道明每天氣怎麼樣') ret = fn(*args,**kwargs) # 在執行目標函數以前 print('下雨了,天氣預報不太準啊') return ret else: ret = fn(*args,**kwargs) # 在執行目標函數以前 return ret return inner return wrapper #語法糖 @裝飾器 @wrapper_out(True) # 先執行wrapper_out(True),返回一個裝飾器,再和@拼接 @裝飾器 def pashan(): #被wrapper裝飾 print('去登山了') pashan()
三、多個裝飾器裝飾同一個函數 app
def wrapper1(fn): def inner(*args,**kwargs): print(1111) ret = fn(*args, **kwargs) print(2222) return ret return inner def wrapper2(fn): def inner(*args, **kwargs): print(3333) ret = fn(*args, *kwargs) print(4444) return ret return inner # 就近原則 @wrapper1 @wrapper2 def func(): print('今天你在作什麼') func() ''' 1111 3333 今天你在作什麼 4444 2222 '''
執行順序:首先@wrapper1裝飾起來,而後獲取到一個新函數是wrapper1中的inner,而後執行@wrapper2,這個時候,@wrapper2裝飾的就是@wrapper1中的inner了,因此執行順序就像:第二層裝飾器前(第一層裝飾器前(目標)第一層裝飾器後)第二層裝飾器後,程序從左到右執行起來 函數