当写了一个装璜器作用在某个函数上时,该函数的元信息就会失落,比方名字,文档,注解和参数签名等。
举例:
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 去装璜内函数来保留元信息。