python functools.wraps

Posted xushukui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python functools.wraps相关的知识,希望对你有一定的参考价值。

我们在使用装饰器的时候,有些函数的功能会丢失,比如func.__name__,func.__doc__,func.__module__
比如下面这个例子:
In [16]: def logged(func):
    ...:     def with_logging(*args,**kwargs):
    ...:         print(func.__name__+" was called ")
    ...:         return func(*args,**kwargs)
    ...:     return with_logging 
    ...: 

In [17]: @logged
    ...: def f(x):
    ...:     """ does some math """
    ...:     return x+x*x
    ...: 

In [18]: f(2)
f was called 
Out[18]: 6

In [19]: print(f.__name__)  # 本来应该输出的是f,但是装饰器装饰之后就失去了func.__name__的功能
with_logging

In [20]: print(f.__doc__)  # 同上
None

那么怎么才能实现这些在装饰器装饰下失去的功能呢?
可以使用 functools 模块下的wraps,functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module__、__name__、__doc__,或者通过参数选择
In [ 9 ]: from functools import wraps
In [10]: def logged(func):
    ...:     @wraps(func)
    ...:     def with_logging(*args,**kwargs):
    ...:         print(func.__name__+" was called ")
    ...:         return func(*args,**kwargs)
    ...:     return with_logging
    ...: 

In [11]: @logged 
    ...: def f(x):
    ...:     """ does some math """
    ...:     return x+x*x
    ...: 

In [12]: print(f.__name__)
f

In [13]: print(f.__doc__)
 does some math 

In [14]: f(2)
f was called 
Out[14]: 6

以上是关于python functools.wraps的主要内容,如果未能解决你的问题,请参考以下文章

python functools.wraps

python functools.wraps装饰器模块

Python 中实现装饰器时使用 @functools.wraps 的理由

python functools.wraps装饰器模块

@functools.wraps(func)

functools.wraps 返回 dict 类型的 __dict__ 而不是 mappingproxy