當寫了一個裝飾器做用在某個函數上時,該函數的元信息就會丟失,好比名字,文檔,註解和參數簽名等。python
舉例:app
import time def timer_func(func): ''' 用於對調用func函數時進行計時 :param func: 函數對象做爲外函數的入參 :return: 內函數 ''' def wrapper(*args,**kwargs): t1=time.time() r=func(*args,**kwargs) t2=time.time() cost=t2-t1 print('time cost %s'%cost) return r return wrapper @timer_func def func(n:int): ''' this is a func test :param n: :return: ''' while n>0: n=n-1 return n >>>func(10000000) time cost 0.6841702461242676 >>>print(func.__name__) wrapper#名字時內函數的名字,再也不是函數自己的名字 >>>print(func.__annotations__) {}#註解丟失 >>>print(func.__doc__) None#文檔丟失
在這種狀況下,使用 functools
庫中的 @wraps
裝飾器來註解底層包裝函數能夠解決這個問題,好比:函數
def timer_func(func): ''' 用於對調用func函數時進行計時 :param func: 函數對象做爲外函數的入參 :return: 內函數 ''' @wraps(func) def wer(*args,**kwargs): t1=time.time() r=func(*args,**kwargs) t2=time.time() cost=t2-t1 print('time cost %s'%cost) return r return wer @timer_func def func(n:int): ''' this is a func test :param n: :return: ''' while n>0: n=n-1 return n >>>func(10000000) time cost 0.6841702461242676 >>>print(func.__name__) func >>>print(func.__annotations__) {'n': <class 'int'>} >>>print(func.__doc__) this is a func test :param n: :return:
所以,在使用裝飾器的場景中,都應該使用functools的wraps去裝飾內函數來保留元信息。this