python-functools库
常用的一些reduce
,warps
,partial
,total_ordering
,singledispatch
,lru_cache
reduce
这个就没啥好说的了
pass
warps
更好的装饰器
调用partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
的简写
可以将被装饰的函数的__name__
、module
、__doc__
和 __dict__
都复制到封装函数去(模块级别常量WRAPPER_ASSIGNMENTS
, WRAPPER_UPDATES
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30from functools import wraps
def wrap(func):
def wrapper(*args,**kwargs):
"""this is wrapper doc"""
print('wrapper call')
return func(*args,**kwargs)
return wrapper
def func():
"this is fun doc"
print('func call')
func()
print('name:',func.__name__)
print('doc:',func.__doc__)
###
使用wraps(func)的输出结果:
wrapper call
func call
name: func
doc: this is fun doc
不使用的输出结果:
wrapper call
func call
name: wrapper
doc: this is wrapper doc
partial
偏函数
用一些默认参数包装一个可调用对象,返回结果是可调用对象,并且可以像原始对象一样对待1
2
3
4
5
6
7def func1(a,*args,g=1,**kwargs):
print(locals())
func2 = partial(func1,66,77,ww=1,rr=2)
func2(2,3)
###
{'kwargs': {'ww': 1, 'rr': 2}, 'args': (77, 2, 3), 'g': 1, 'a': 66}
total_ordering
自动生成比较方法
如果一个类如果定义了__lt__
、__le__
、__gt__
、__ge__
这些方法中的至少一个,使用该装饰器,则会自动的把其他几个比较函数也实现在该类中,但是__eq__
必须自己定义,不定义会使用默认的hash(id(obj))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21from functools import total_ordering
class T:
def __init__(self, v):
self.v = v
def __le__(self, other):
return self.v <= other.v
t1 = T(12)
t2 = T(12)
print(t1 < t2)
print(t1 == t2)
###
不使用total_ordering时会报错:TypeError: '<' not supported between instances of 'T' and 'T'
使用时输出:
True
False
singledispatch
单分派范函数,类似重载
1 | from functools import singledispatch |
使用singledispatch
可以把不同的处理模块分开不用在里面if else
了
lru_cache
LRU模型缓存装饰器
可以将函数的处理结果缓存起来,减少调用次数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from functools import lru_cache
cnt = 0
def ff(n):
global cnt
cnt += 1
if n < 2:
return n
return ff(n-2)+ff(n-1)
ff(21)
print(cnt)
###
使用lru_cache()的输出为 22 ,也就是说ff函数总共调用22次
不使用的输出为 35421,可以看出差距还是有点大的lru_cache(maxsize=128,typed=False)
可以使用两个可选参数
第一个就是大小了,最好设为2的幂,如果设为None
,那么会无限存储。
typed 参数如果设为 True,把不同参数类型得到的结果分开保存,即把通常认为相等的浮点数和整数参数(如 1 和 1.0)区分开。lru_cache
使用字典存储结果,而且键根据调用时传入的定位参数和关键字参数创建,所以被 lru_cache
装饰的函数,它的所有参数都必须是可散列的。