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


posted @ 2018-07-20 20:15  xushukui  阅读(146)  评论(0编辑  收藏  举报