Python functools其他都比较简单,挑partial和wraps扯扯淡
官网文档说的真是不好理解,就当作是把一个函数,绑定部分或者全部参数后生成一个新版本的函数.
还是很绕口,看例子
from functools import partial
>>> def add(a, b, kw="add"):
... return a+b, kw
...
>>> add
<function add at 0x2afeaf7cecf8>
>>> plus3 = partial(add, 3, kw="add_3")
>>> plus3.func
<function add at 0x2afeaf7cecf8>
>>> plus3.args
(3,)
>>> plus3.keywords
{'kw': 'add_3'}
>>> plus3(5)
(8, 'add_3')
plus3就是创建一个新函数(准确的说,是叫partial object,不用管,你就当函数,不影响使用):args使用你预置的3, kwargs也update你指定的关键字参数,被修改的args和kwargs最终都被应用到add函数上
文档说的比较详细,如果不使用这个wraps,那么原始函数的__name__
和__doc__
都会丢失
不使用wraps例子
>>> def my_decorator(f):
... def wrap(*args, **kwargs):
... print "decorated func called"
... return f(*args, **kwargs)
... return wrap
...
>>>
>>> @my_decorator
... def ff():
... """ff doc str"""
... print "ff called"
...
>>>
>>> ff
>>> ff.__doc__
>>> ff.__name__
'wrap'
>>> ff()
decorated func called
ff called
可以看到ff.__doc__
丢失,ff.__name__
被覆盖。下面是使用wraps例子
>>> from functools import wraps
>>> def my_decorator2(f):
... @wraps(f)
... def wrap(*args, **kwargs):
... print "decorated func called"
... return f(*args, **kwargs)
... return wrap
...
>>> @my_decorator2
... def gg():
... """gg doc str"""
... print "gg called"
...
>>> gg.__doc__
'gg doc str'
>>> gg.__name__
'gg'
>>> gg()
decorated func called
gg called
gg.__doc__
和gg.__name__
被保留。所以呢,为了便于调试,尽量保留原始函数信息,日志里才能更清楚的输出各种信息