Python裝飾器分兩種情況:
1.如果decorator本身不用傳入?yún)?shù)的話,只是接受一個(gè)函數(shù)(當(dāng)然也可以把接受的函數(shù)作為參數(shù)同仆,為了區(qū)別,我們暫且將他們分開),并返回一個(gè)函數(shù)的話盐类,當(dāng)使用@log時(shí)即把目標(biāo)函數(shù)接入;
2.如果decorator本身需要傳入?yún)?shù)呛谜,那我們首先就需要在外層嵌套一個(gè)傳入?yún)?shù)的接口在跳,然后再接受函數(shù)并返回一個(gè)函數(shù),內(nèi)層則就是重復(fù)第一種情況隐岛,當(dāng)時(shí)用@log('要傳入的參數(shù)')猫妙,log('要傳入的參數(shù)')就相當(dāng)于第一種情況的log,也許這樣說你還不是很能理解聚凹,我把廖大大的代碼稍微做一點(diǎn)點(diǎn)改變割坠,只改變下函數(shù)的名稱:
1. 裝飾器本身不用傳入?yún)?shù),只接收函數(shù)func
def decorator(func):
@functools.wraps(func)
def wrapper(*args, *kw):
print('call %s():' % func.name)
return func(args, **kw)
return wrapper
@decorator
def f():
pass
2. 裝飾器本身需要傳入?yún)?shù)妒牙,再接收函數(shù)func
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, *kw):
print('%s %s():' % (text, func.name))
return func(args, **kw)
return wrapper
return decorator
@log('execute')
def f():
pass
其中第二種情況@log('execute')就是傳入了字符串參數(shù)的decorator彼哼,傳入?yún)?shù)之后就完全等同于第一種情況的@decorator,log只是在第一種情況下作為實(shí)現(xiàn)傳入字符串參數(shù)功能的外層湘今,可以發(fā)現(xiàn)第二種情況的內(nèi)層完全和第一種情況相同沪羔。線性的把第二種情況展開:首先log()傳入字符串參數(shù),然后返回decorator接受目標(biāo)函數(shù)func象浑,返回wrapper蔫饰,最后wrapper輸出內(nèi)容并運(yùn)行目標(biāo)函數(shù)。明顯傳入字符串參數(shù)之后完全和第一種情況一致愉豺。
其他相關(guān)幫助理解資料:
探究functools模塊wraps裝飾器的用途 - 大道曙光
[譯] 12步輕松搞定python裝飾器