你可能在随意的 Python 代码中见过这个 @wraps 的东西,你可能想知道这到底是什么?
元数据指的是函数本身的数据。
def apple(): '''a function that prints apple''' print('apple')print(apple.__name__) # appleprint(apple.__doc__) # 打印apple的函数
例子包括函数名 .__name__ 或函数 docstring .__doc__
装饰器用于改变函数的行为方式,而无需修改任何源代码。
def greet(name): return 'hello ' + nameprint(greet('tom')) # hello tom
在这里,我们有一个普通的 greet 功能
def add_exclamation(func): def wrapper(name): return func(name) + '!' return wrapper@add_exclamationdef greet(name): return 'hello ' + nameprint(greet('tom')) # hello tom!
我们通过在 greet() 上添加 @add_exclamation 来用 add_exclamation() 来装饰 greet()。这里,add_exclamation 是装饰器,greet 是被装饰的函数。
请注意,greet() 的行为已经改变,而我们根本没有编辑 greet() 的源代码。这是装饰器的功劳。
def add_exclamation(func): def wrapper(name): return func(name) + '!' return wrapper@add_exclamationdef greet(name): return 'hello ' + nameprint(greet('tom')) # hello tom!
这是完全相同的:
def add_exclamation(func): def wrapper(name): return func(name) + '!' return wrapperdef greet(name): return 'hello ' + namegreet = add_exclamation(greet)print(greet('tom')) # hello tom!
注意 “greet = add_exclamation(greet) ”一行。
# 没有装饰def greet(name): '''says hello to someone''' return 'hello ' + nameprint(greet.__name__) # greetprint(greet.__doc__) # says hello to someone
在这里,我们可以顺利打印 greet() 的元数据。
# 加了装饰def add_exclamation(func): def wrapper(name): return func(name) + '!' return wrapper@add_exclamationdef greet(name): '''says hello to someone''' return 'hello ' + nameprint(greet.__name__) # wrapperprint(greet.__doc__) # None
用 add_exclamation 装饰 greet 后,请注意元数据发生了变化。__name__ 变成了 “wrapper”,而 __doc__ 变成了 wrapper 的 docstring。
这是因为当我们装饰 greet 时,我们实际上是在做这件事:
greet = add_exclamation(greet)
我们正在将 greet 重新分配给一个由 add_exclamation 返回的函数--wrapper。
这就是为什么当我们尝试打印 greet.__name__ 和 greet.__doc__ 时,会打印 wrapper 的元数据的原因。
from functools import wrapsdef add_exclamation(func): @wraps(func) def wrapper(name): return func(name) + '!' return wrapper@add_exclamationdef greet(name): '''says hello to someone''' return 'hello ' + nameprint(greet.__name__) # greetprint(greet.__doc__) # says hello to someone
请注意,尽管使用了 ad_exclamation 装饰,greet 的元数据还是回到了正常状态。
更具体地说,@wraps(something) 用 something 的元数据覆盖了函数的元数据。这样,我们原来函数的元数据就不会丢失了。
本文链接:http://www.28at.com/showinfo-26-100714-0.htmlPython 中的 @wraps 到底是个啥东西?
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 聊聊2024年Rust加密生态系统