裝飾器本質(zhì)
裝飾器本質(zhì)上是用一個(gè)新的函數(shù)替換原先的函數(shù).
@logged
def f(x):
"""does some math"""
return x + x * x
本質(zhì)上是如下語(yǔ)句
f = logged(f)
使用wraps保存原函數(shù)的name和doc屬性
單純使用之前的裝飾器會(huì)出現(xiàn)一個(gè)問(wèn)題 -- 用新函數(shù)替代老函數(shù)后, 我們丟失了老函數(shù)的一些屬性信息, 比如name, doc_, 這在規(guī)范的工程代碼中是很不好的.
還好, python為我們提供了一個(gè)簡(jiǎn)單的解決方案, 只要在裝飾函數(shù)的定義上加上一個(gè)@wraps(func)
就可以了.
from functools import wraps
def logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging
@logged
def f(x):
"""does some math"""
return x + x * x
print f.__name__ # prints 'f'
print f.__doc__ # prints 'does some math'
這個(gè)@wraps(func)記號(hào)會(huì)自動(dòng)把函數(shù)名, docstring, 參數(shù)列表等原函數(shù)屬性都一一復(fù)制到最后替換的新函數(shù)這里, 讓新函數(shù)的信息顯示正確.
參考資料
https://stackoverflow.com/questions/308999/what-does-functools-wraps-do
https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators/1594484#1594484