標籤:
這是一個很有用的裝飾器。看過前一篇反射的朋友應該知道,函數是有幾個特殊屬性比如函數名,在被裝飾後,上例中的函數名foo會變成封裝函數的名字 wrapper,如果你希望使用反射,可能會導致意外的結果。這個裝飾器可以解決這個問題,它能將裝飾過的函數的特殊屬性保留。
import timeimport functools def timeit(func): @functools.wraps(func) def wrapper(): start = time.clock() func() end =time.clock() print ‘used:‘, end - start return wrapper @timeitdef foo(): print ‘in foo()‘ foo()print foo.__name__
首先注意第5行,如果注釋這一行,foo.__name__將是‘wrapper‘。另外相信你也注意到了,這個裝飾器竟然帶有一個參數。實際上,他還有 另外兩個可選的參數,assigned中的屬性名稱將使用賦值的方式替換,而updated中的屬性名稱將使用update的方式合并,你可以通過查看 functools的原始碼獲得它們的預設值。對於這個裝飾器,相當於wrapper = functools.wraps(func)(wrapper)。
# -*- coding=utf-8 -*- from functools import wraps def my_decorator(func): @wraps(func) def wrapper(*args, **kwargs): print(‘Calling decorated function...‘) return func(*args, **kwargs) return wrapper
@my_decorator def example(): """Docstring""" print(‘Called example function‘)print(example.__name__, example.__doc__)
列印出:example Docstring
python wraps裝飾器