其实整个functools模块都值得讲一下,我们后面会出一个专门的文章来讲。今天我们先来看下functools.wraps。
在本节内容开始前,首先要了解什么是修饰符?可以参考我们之前整理的一篇文章。
Python高性能计算之修饰符
这这篇文章中我们可以看到,修饰器的一般形式是:
代码语言:javascript复制def works_for_all(func):
def inner(*args, **kwargs):
print("I can decorate any function")
return func(*args, **kwargs)
return inner
@works_for_all
def ff(*args, **kwargs):
print(args)
print(kwargs)
如果我们此时打印ff的名字:
代码语言:javascript复制print(ff.__name__)
>>> inner
可以看到,由于使用了修饰符,函数的__name__
属性已经被修改成了修饰器中闭包函数的名字。这样会导致什么问题呢?如果两个函数的修饰符都是works_for_all
,那么这两个函数的名字就一样了。
@works_for_all
def ff2(*args, **kwargs):
return 1
打印出两个函数的名字:
代码语言:javascript复制print(ff.__name__)
>>> inner
print(ff2.__name__)
>>> inner
如何解决这个问题呢?即便使用了修饰符,__name__
属性应该还是保持原来的函数名,此时functools.wraps
就派上用场了。
from functools import wraps
def works_for_all(func):
@wraps(func)
def inner(*args, **kwargs):
print("I can decorate any function")
return func(*args, **kwargs)
return inner
@works_for_all
def ff(*args, **kwargs):
print(args)
print(kwargs)
@works_for_all
def ff2(*args, **kwargs):
return 1
增加@functools.wraps(func)
, 可以保持当前装饰器去装饰的函数的 name 的值不变.
此时再打印两个函数的名字:
代码语言:javascript复制print(ff.__name__)
print(ff2.__name__)
>>> ff
>>> ff2