在人类世界中有一些大佬,经过细心装扮之后,自身的属性可以变得让人雌雄莫辨。(我没有在说 Abbily
,我是在说花木兰!)
在 Python
世界中也是一样,一些函数经过装饰器的悉心装饰之后,一些属性也会变得令人迷惑。
先定义一个啥都不干,但很淳朴的函数,顺便看看它的函数名和文档字符串:
def iron_egg():
"""我是铁蛋儿~"""
return
print(iron_egg.__name__)
print(iron_egg.__doc__)
"""输出:
iron_egg
我是铁蛋儿~
"""
再定义一个啥都不干,但很美丽的装饰器:
def decorator(func):
def spring_blossom(*args, **kwargs):
"""我是春花儿~"""
return func(*args, **kwargs)
return spring_blossom
手动用美丽的装饰器装饰一下淳朴的函数,然后再检查一下函数名和文档字符串:
iron_egg = decorator(iron_egg)
print(iron_egg.__name__)
print(iron_egg.__doc__)
"""
spring_blossom
我是春花儿~
"""
可见在装饰器的作用下,铁蛋儿变成了春花儿,这大多数情况下并不是我们想要的行为。
如何保持函数的本来面目呢?可以使用 functools
模块提供的 wraps
装饰器。
from functools import wraps
def decorator(func):
@wraps(func)
def spring_blossom(*args, **kwargs):
"""我是春花儿~"""
return func(*args, **kwargs)
return spring_blossom
@decorator
def iron_egg():
"""我是铁蛋儿~"""
return
print(iron_egg.__name__)
print(iron_egg.__doc__)
"""
iron_egg
我是铁蛋儿~
"""
可见,在 @wraps(func)
的帮助下,铁蛋儿还是铁蛋儿,它拒绝了女装,果然不负众望。(你很失望?你不对劲儿!)
那么 functools.wraps
这个东西为何如此神奇?实际上它用到了 functools
中的另外一个 partial
函数,这就留待下回分解吧!