装饰器本质
装饰器本质上是用一个新的函数替换原先的函数.
@logged
def f(x):
"""does some math"""
return x + x * x
本质上是如下语句
f = logged(f)
使用wraps保存原函数的name和doc属性
单纯使用之前的装饰器会出现一个问题 -- 用新函数替代老函数后, 我们丢失了老函数的一些属性信息, 比如name, doc_, 这在规范的工程代码中是很不好的.
还好, python为我们提供了一个简单的解决方案, 只要在装饰函数的定义上加上一个@wraps(func)
就可以了.
from functools import wraps
def logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging
@logged
def f(x):
"""does some math"""
return x + x * x
print f.__name__ # prints 'f'
print f.__doc__ # prints 'does some math'
这个@wraps(func)记号会自动把函数名, docstring, 参数列表等原函数属性都一一复制到最后替换的新函数这里, 让新函数的信息显示正确.
参考资料
https://stackoverflow.com/questions/308999/what-does-functools-wraps-do
https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators/1594484#1594484
网友评论