需求背景
假若我希望编写一个装饰器,套用给各个测试用例来进行一些统计,诸如,当前用例执行的api,参数,通过与否,预期结果,就必须需要用例方法的相关信息。
前言
都知道装饰器是在原有函数的基础上,增强一些功能。但是在某些情况下,被装饰的函数的某些属性会被改变
case1
```python import time
def run_time(func): def wrapper(args, **kwargs): “””时间装饰器””” time1 = time.time() func(args, **kwargs) time2 = time.time() cost_time = time2 - time1 return f”函数花了{cost_time}秒” return wrapper
@run_time def test(): “””测试””” print([i for i in range(1, 100001) if i % 200 == 0])
if __name__ == '__main__':
print(test.__name__)
print(test.__doc__)
"""
结果
# wrapper
# 时间装饰器
“””

- 期望它输出的应该是test,测试,但是输出的变成了装饰器的内部函数属性。
- 我们知道@run_time装饰器实际上就等于test = run_time(test),此时我们打印test.__name__实际上test已经指向了wrapper,这样会造成我们打印的时候会打印装饰器的内嵌函数的名字和注释。
<a name="UBzTu"></a>
# 使用wraps装饰器解决
- wraps可以将原函数对象的指定属性复制给包装函数对象, 默认有__module__、__name__、__doc__、__qualname__、__annotations__或者通过参数选择
```python
import time
from functools import wraps
def run_time(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""时间装饰器"""
time1 = time.time()
func(*args, **kwargs)
time2 = time.time()
cost_time = time2 - time1
return f"函数花了{cost_time}秒"
return wrapper
@run_time
def test():
"""测试"""
print([i for i in range(1, 100001) if i % 200 == 0])
if __name__ == '__main__':
print(test.__name__)
print(test.__doc__)
"""
结果:
test
测试
"""