装饰器,其原理是在不修改原功能函数的基础上而扩展新的功能,而@wraps的主要作用是来消除被装饰之后的副作用,保留被装饰函数的原有属性。
举例:
如下fun没有被装饰之前获取函数名,字符串注释
def decorator(fun):
def wrapper():
"""wrapper文档字符串"""
fun()
return wrapper
def fun():
"""fun文档字符串"""
print("----fun----")
print(fun.__name__) # 函数名
print(fun.__doc__) # 文档注释
运行结果:
fun
fun文档字符串
调用装饰器之后,运行结果:
def decorator(fun):
def wrapper():
"""wrapper文档字符串"""
fun()
return wrapper
@decorator
def fun():
"""fun文档字符串"""
print("----fun----")
print(fun.__name__)
print(fun.__doc__)
运行结果:
wrapper
wrapper文档字符串
由此可见被装饰后的fun指向了wrapper,通过@wraps解决:
from functools import wraps
def decorator(fun):
@wraps(fun)
def wrapper():
"""wrapper文档字符串"""
fun()
return wrapper
@decorator
def fun():
"""fun文档字符串"""
print("----fun----")
print(fun.__name__) # 函数名
print(fun.__doc__) # 文档注释
运行结果:
fun
fun文档字符串