说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不受影响,Python 的 functools 包中提供了一个 @wraps 的装饰器来消除这样的副作用。写一个 decorator 的时候,最好在实现之前加上 functools 的 wrap,它能保留原有函数的名称和 docstring。
示例如下:
>>> from functools import wraps
>>> def my_decorator(f):
... @wraps(f)
... def wrapper(*args, **kwds):
... print('Calling decorated function')
... return f(*args, **kwds)
... return wrapper
...
>>> @my_decorator
... def example():
... """Docstring"""
... print('Called example function')
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'
如果不使用这个装饰器工厂函数,则 example 函数的名称将变为 'wrapper'
,并且 example()
原本的文档字符串将会丢失。
它的语法是 :
import functools
@functools.wraps(wrapped,
assigned=WRAPPER_ASSIGNMENTS,
updated=WRAPPER_UPDATES)
这是一个便捷函数,用于在定义包装器函数时发起调用 update_wrapper() 作为函数装饰器。
它等价于:
import functools
functools.partial(update_wrapper,
wrapped=wrapped,
assigned=assigned,
updated=updated)
源码为:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',
'__annotations__')
WRAPPER_UPDATES = ('__dict__',)
def wraps(wrapped,
assigned = WRAPPER_ASSIGNMENTS,
updated = WRAPPER_UPDATES):
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
我们可以看出,wraps 函数其实就是一个修饰器版的 update_wrapper 函数,它的功能和 update_wrapper是一模一样的。我们可以修改我们上面的自定义修饰器的例子,做出一个更方便阅读的版本。
更新时间:2022-01-20 22:47:52 标签:python 装饰器