裝飾器算是Python非常有用的特性之一了譬挚,因為它實現(xiàn)了DRYC(不要重復你自己的代碼),但是它非常難駕馭酪呻,十分不好理解减宣。
def doc_it(f):
def decorator(*args, **kwargs):
print('This is doc')
return f(*args, **kwargs)
return decorator
這就是一個標準的裝飾器了,它能在所裝飾的函數(shù)調(diào)用前自動輸出一行文本
@doc_it
def func():
print('a')
上面的代碼做的事情就是把func作為參數(shù)傳入了裝飾器doc_it玩荠,相當于func=doc_it(func)漆腌,我們可以得到一個新函數(shù)贼邓,盡管我們還可以通過func調(diào)用它,但是輸出一下func._name_發(fā)現(xiàn)會得到decorator闷尿,說明它確實已經(jīng)變成了另外一個函數(shù)
用這個有用的特性我們可以實現(xiàn)一個函數(shù)內(nèi)部緩存的效果塑径,原理如下:
def count_it(f):
count = [0]
def decorator(*args, **kwargs):
count[0] += 1
print('count is {count}'.format(count[0]))
return f(*args, **kwargs)
return decorator
這個裝飾器我們可以輕易統(tǒng)計出一個函數(shù)調(diào)用的次數(shù),但是我們那個緩存為什么要使用list類型呢填具,用一個int類型豈不是更好统舀,但是這里只能用可變類型的數(shù)據(jù),具體原因參考默認參數(shù)劳景。
然后我們用裝飾器實現(xiàn)限制函數(shù)調(diào)用的頻率就很簡單了
from time import time
def time_required(f):
last = [time()]
def decorator(*args, **kwargs):
if time() - last[0] < 10:
raise RuntimeError('This time not allow, please wait to {time}'.format(time=last[0] + 10))
last[0] = time()
return f(*args, **kwargs)
return decorator