函式>>>裝飾器

裝飾器是由名稱空間 函式物件 閉包函式 組合而來

簡易版裝飾器

1、給一個函式新增統計時間的功能def func(): pass2、在呼叫該函式的前後添加了一些額外的程式碼start_time = time。time() index() endtime = time。time()3、統計時間的程式碼在程式的很多地方都需要反覆執行 >>> 封裝成函式def get_time(func): start_time = time。time() index() endtime = time。time()4、封裝成函式之後為了解決相容性問題(能夠統計不同函式的執行時間)def outter(func): #func = index def get_time(): start_time = time。time() func() end_time = time。time return get_timeindex = outeer(index)index()

函式>>>裝飾器

裝飾器引數解決問題

def outer(func): def get_time(*args,**kwargs): start_time = time。time func(*args,**kwargs) end_time = time。time return get_timeindex = outer(index)index()

函式>>>裝飾器

裝飾器解決返回值問題

def outer(func): def get_time(*args,**kwargs): start_time = time。time res = func(*args,**kwargs) end_time = time。time return res return get_timeindex = outer(index)index()

函式>>>裝飾器

裝飾器模板

def outer(func): def inner(*args,**kwargs): #執行被裝飾函式(物件)之前可以執行的其他操作 res = func(*args,**kwargs) #執行被裝飾函式(物件)之後可以執行的其他操作 return res return inner

函式>>>裝飾器

裝飾器語法糖

@outerdef index(): pass#1、語法糖必須緊挨著被裝飾器物件#2、 語法糖會自動將緊挨著的物件當作引數加()傳入函式自動呼叫 index = outer(index)#3、如果上方沒有其他語法糖則直接使用與被裝飾物件相同的變數名接收裝飾器返回值

函式>>>裝飾器

語法糖使用(雙層、三層)

@outer1 # index = outer1(outer函式的返回值(函式名))@outer2 # outer2函式的返回值(函式名) = outer2(outer3函式的返回值(函式名))@outer3 # outer3函式的返回值(函式名) = outer3(真正的index)def index(): pass# 語法糖由下往上自動執行

函式>>>裝飾器

裝飾器修復技術

help() # 可以檢視函式的基本資訊(函式名 函式註釋)‘’‘如何讓做到無法輕易看出是否被裝飾’‘’from functools import wraps # 固定句式def outer(func): @wraps(func) # 固定句式 def inner(*args,**kwargs): # 執行被裝飾函式(物件)之前可以執行的其他操作 res = func(*args,**kwargs) # 執行被裝飾函式(物件)之後可以執行的其他操作 return res return inner

函式>>>裝飾器

有參裝飾器

如果裝飾器內部還需要額外的引數from functools import wraps # 固定格式def outers(others): def outer(func): @wraps(func) #固定格式 def inner(*args,**kwargs): # 執行被裝飾器函式(物件)之前可以執行的其他操作 outers #執行被裝飾函式(物件)之後可以執行的其他操作 return res return inner return outer@outers(123) # 先執行outers函式 之後再執行語法糖功能

函式>>>裝飾器