需求背景
假若我希望编写一个装饰器,套用给各个测试用例来进行一些统计,诸如,当前用例执行的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
# 时间装饰器
“””
![image.png](https://cdn.nlark.com/yuque/0/2022/png/1608527/1651559877011-d8544871-23de-41b0-8261-07e16875da96.png#clientId=u85482d78-b7f8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=740&id=u37b23d85&margin=%5Bobject%20Object%5D&name=image.png&originHeight=925&originWidth=1768&originalType=binary&ratio=1&rotation=0&showTitle=false&size=112511&status=done&style=none&taskId=u2fea421c-899c-449c-81c4-f8a220f1905&title=&width=1414.4)
- 期望它输出的应该是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
测试
"""