说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python 内置模块 functools 的一个高阶函数 update_wrapper() 的主要功能是负责复制原函数的一些属性,如 moudle、name、doc
等,如果没 update_wrapper,那么被装饰器修饰的函数就会丢失其上面的一些属性信息。
此方法用于更新包装函数的元数据,以反映包装函数的元数据,从而提高代码的可读性和可重用性。
update_wrapper() 语法为:
import functools
functools.update_wrapper(wrapper,
wrapped,
assigned=WRAPPER_ASSIGNMENTS,
updated=WRAPPER_UPDATES)
以下参数:
为了更好地理解这个方法,让我们观察一些在 Python 中使用 decorator 和 partials 的案例。
import functools
# 定义装饰器
def hi(func):
def wrapper():
"Hi has taken over Hello Documentation"
print("Hi geeks")
func()
# 重点:更新修饰器
# functools.update_wrapper(wrapper, func)
return wrapper
@hi
def hello():
"this is the documentation of Hello Function"
print("Hey Geeks")
执行代码:
hello.__name__
# wrapper
hello.__doc__
# Hi has taken over Hello Documentation
help(hello)
'''
Help on function wrapper in module __main__:
wrapper()
Hi has taken over Hello Documentation
'''
在上面的示例中,当我们使用 decorator 函数 hi 并使用其包装器包装 hello 时,函数 hello 的模块级常量,如 __name__
、__doc__
等,将被函数 hi 中包装器的常量替换。
我们解开注释更新修饰器 functools.update_wrapper(wrapper, func)
代码,再执行:
hello.__name__
# 'hello'
hello.__doc__
# 'this is the documentation of Hello Function'
help(hello)
'''
Help on function hello in module __main__:
hello()
this is the documentation of Hello Function
'''
可以看到,这些元信息成为了被装饰函数的的信息。
更新一个 wrapper 函数以使其类似于 wrapped 函数。 可选参数为指明原函数的哪些属性要直接被赋值给 wrapper 函数的匹配属性的元组,并且这些 wrapper 函数的属性将使用原函数的对应属性来更新。 这些参数的默认值是模块级常量 WRAPPER_ASSIGNMENTS (它将被赋值给 wrapper 函数的 __module__
, __name__
, __qualname__
, __annotations__
和 __doc__
即文档字符串) 以及 WRAPPER_UPDATES (它将更新 wrapper 函数的 __dict__
即实例字典)。
为了允许出于内省和其他目的访问原始函数(例如绕过 lru_cache() 之类的缓存装饰器),此函数会自动为 wrapper 添加一个指向被包装函数的 __wrapped__
属性。
此函数的主要目的是在 decorator 函数中用来包装被装饰的函数并返回包装器。 如果包装器函数未被更新,则被返回函数的元数据将反映包装器定义而不是原始函数定义,这通常没有什么用处。
update_wrapper() 可以与函数之外的可调用对象一同使用。 在 assigned 或 updated 中命名的任何属性如果不存在于被包装对象则会被忽略(即该函数将不会尝试在包装器函数上设置它们)。 如果包装器函数自身缺少在 updated 中命名的任何属性则仍将引发 AttributeError。
更新情况如下:
__wrapped__
属性。__annotations__
属性。__wrapped__
属性现在总是指向被包装的函数,即使该函数定义了 __wrapped__
属性。更新时间:2022-01-20 22:35:31 标签:python 函数