01
引言
大家好,我是AI算法之道!
Python是我最喜欢的编程语言之一,它向来以其简单性、多功能性和可读性而闻名。
在Python编程中有各种各样的小技巧,在本文中,我们将深入探讨Python3中@wraps
的原理和用法,希望可以帮助到大家!
02
函数的元数据
def apple():
'''a function that prints apple'''
print('apple')
print(apple.__name__) # apple
print(apple.__doc__) # a function that prints apple
.__name__
或函数的描述.__doc__
(上面只展示了两个例子,其实还有更多)。03
装饰器如何工作?
def greet(name):
return 'hello ' + name
print(greet('tom')) # hello tom
greet()
,我们来看看装饰器后的效果,如下:def add_exclamation(func):
def wrapper(name):
return func(name) + '!'
return wrapper
def greet(name):
return 'hello ' + name
print(greet('tom')) # hello tom!
greet()
的上方添加@add_exclamation
,用 add_exclamation()
来装饰 greet()
。这里,add_exclamation
是装饰器,greet
是被装饰者(被装饰的函数)。请注意,greet() 函数的行为已被更改(输出现在多了一个 !)--我们完全没有编辑函数 greet() 的源代码。这就是装饰器的功劳。
04
装饰器语法
我们来看下装饰器的语法:
def add_exclamation(func):
def wrapper(name):
return func(name) + '!'
return wrapper
def greet(name):
return 'hello ' + name
print(greet('tom')) # hello tom!
def add_exclamation(func):
def wrapper(name):
return func(name) + '!'
return wrapper
def greet(name):
return 'hello ' + name
greet = add_exclamation(greet)
print(greet('tom')) # hello tom!
请注意 greet = add_exclamation(greet)
透过这一行,大家可以看出装饰器的神奇之处。
05
装饰器会导致元数据丢失
接着我们来讲解上述两种写法对元数据的影响,首先是普通的函数如下:
# undecorated
def greet(name):
'''says hello to someone'''
return 'hello ' + name
print(greet.__name__) # greet
print(greet.__doc__) # says hello to someone
在这里,我们可以顺利打印出函数 greet()
的元数据。我们来看看带装饰器的函数,如下:
# decorated
def add_exclamation(func):
def wrapper(name):
return func(name) + '!'
return wrapper
def greet(name):
'''says hello to someone'''
return 'hello ' + name
print(greet.__name__) # wrapper
print(greet.__doc__) # None
add_exclamation
修饰函数 greet
之后,请注意元数据发生了变化。__name__
的输出变成了 "wrapper"
,而 __doc__
变成了函数 wrapper
的 docstring
。greet = add_exclamation(greet)
add_exclamation
返回的函数 - wrapper。greet.__doc__
时,会打印出wrapper 的元数据。06
@wraps防止元数据丢失
@wraps
的定义:from functools import wraps
def add_exclamation(func):
def wrapper(name):
return func(name) + '!'
return wrapper
def greet(name):
'''says hello to someone'''
return 'hello ' + name
print(greet.__name__) # greet
print(greet.__doc__) # says hello to someone
大家需要注意,尽管我们使用了add_exclamation
进行装饰,函数greet
的元数据恢复到了正常状态。
更具体地说,@wraps(something)
用 something
的元数据覆盖了函数的元数据。这样就不会丢失原始函数的元数据。
07
总结
本文重点介绍了python中装饰器的@wraps
的基本原理和用法用例,希望这些小技巧可以帮助到大家,提升大家的工作效率!
您学废了吗?
点击上方小卡片关注我
添加个人微信,进专属粉丝群!