調(diào)試遞歸函數(shù)時(shí)我們常需要打印出每一步的參數(shù)及返回值犀呼,這時(shí)寫個(gè)裝飾器十分高效:
def trace(func):
def wrapper(*args, **kw):
result = func(*args, **kw)
print(f"{func.__name__}({args}, {kw}) --> {result}")
return result
return wrapper
@trace
def fibonacci(n):
if n in (0, ):
return 0
return fibonacci(n-1) + fibonacci(n-2)
fibonacci(4)
>>>
fibonacci((1,), {}) --> 0
fibonacci((0,), {}) --> 0
fibonacci((2,), {}) --> 0
fibonacci((1,), {}) --> 0
fibonacci((3,), {}) --> 0
這種寫法的缺陷在于變量fibonacci變成了wrapper:
help(fibonacci)
>>>
Help on function wrapper in module __main__:
wrapper(**args, **kwargs)
print(fibonacci)
>>>
<function trace.<locals>.wrapper at 0x0000012B1C774598>
為了維護(hù)函數(shù)的接口国裳,修飾后的函數(shù),必須保留原函數(shù)的某些標(biāo)準(zhǔn)python屬性,例如吵聪,__name__劲装,__module__胧沫。因此我們需要wraps來裝飾wrapper:
from functools import wraps
def trace(func):
@wraps
def wrapper(*args, **kw):
result = func(*args, **kw)
print(f"{func.__name__}({args}, {kw}) --> {result}")
return result
return wrapper
要點(diǎn)
- 內(nèi)置的functools模塊提供了名為wraps的裝飾器,開發(fā)者定義自己的裝飾器時(shí)占业,應(yīng)用wraps對(duì)其做一些處理