Python functools详解

2023-01-31 01:01:35 python functools 详解

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__被保留。所以呢,为了便于调试,尽量保留原始函数信息,日志里才能更清楚的输出各种信息

相关文章