当写了一个装饰器作用在某个函数上时,该函数的元信息就会丢失,比如名字,文档,注解和参数签名等。
举例:
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去装饰内函数来保留元信息。
原文:https://www.cnblogs.com/qianfanwaer/p/14839385.html