全部方法
__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial',
'partialmethod', 'singledispatch']
functools.partial ,functool.update_wrapper,functool.wraps在装饰器部分已经介绍了.
functools.cmp_to_key
将老式比较函数转换成key函数,用在接受key函数的方法中(such as sorted(), min(), max(), heapq.nlargest(), heapq.nsmallest(), itertools.groupby())
一个比较函数,接收两个参数,小于,返回负数,等于,返回0,大于返回整数
key函数,接收一个参数,返回一个表明该参数在期望序列中的位置
例如:
sorted(iterable, key=cmp_to_key(locale.strcoll))
locale.strcoll是比较根据语言设置来比较字符串
functools.total_ordering(cls)
@total_ordering
class Student:
def __eq__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) ==
(other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))
functools.reduce(function, iterable[, initializer]
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方说对一个序列求和,就可以用reduce
实现:
from functools import reduce
reduce(lambda x,y: x+y, [1, 2, 3]) # 6
reduce(lambda x, y: x+y, [1,2,3], 9) # 15
functools.lru_cache
functools.lru_cache的作用主要是用来做缓存,他能把相对耗时的函数结果进行保存,避免传入相同的参数重复计算。同时,缓存并不会无限增长,不用的缓存会被释放。
递归:
import time
import functools
def clock(func):
# functools.wraps(func)装饰器的作用是将func函数的相关属性复制到clock中
# 比如说__name__, __doc__等等
@functools.wraps(func)
def clocked(*args, **kwargs):
t0 = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - t0
name = func.__name__
arg_lst = []
if args:
arg_lst.append(', '.join(repr(arg) for arg in args))
if kwargs:
pairs = ['%s=%r' % (k, w) for k, w in sorted(kwargs.items())]
arg_lst.append(', '.join(pairs))
arg_str = ', '.join(arg_lst)
print('[%0.8fs] %s(%s) -> %r ' % (elapsed, name, arg_str, result))
return result
from clockdeco import clock
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
if __name__=='__main__':
print(fibonacci(6))
# 有大量的重复函数计算在整个运行过程中,比如fibonacci(1),fibonacci(2)就分别运行了多次。
# 现在给fibonacci()函数加上@functools.lru_cache()装饰器进行缓存实现
from clockdeco import clock
@functools.lru_cache()
@clock
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2) + fibonacci(n-1)
if __name__=='__main__':
print(fibonacci(6))
另外:functools.lru_cache(maxsize=128, typed=False)有两个可选参数,我们来看看他们分别代表的意义。
* maxsize代表缓存的内存占用值,超过这个值之后,就的结果就会被释放,然后将新的计算结果进行缓存,其值应当设为2的幂 *
* typed若为True,则会把不同的参数类型得到的结果分开保存 *
functools.singledispatch
本装饰器用来实现函数对多个类型进行重载。比如同样的函数名称,对不同类型有不同功能实现。优先执行已注册类型
from functools import *
@singledispatch
def fun(arg, verbose=False):
if verbose:
print('singledispatch:', end=' ')
print(arg)
@fun.register(list)
def _(arg, verbose=False):
if verbose:
print('list:')
for i, elem in enumerate(arg):
print(i, elem)
@fun.register(int)
def _(arg, verbose=False):
if verbose:
print('int')
print(arg)
fun(100, verbose=True)
fun([1, 2, 3], verbose=True)
functools.partialmethod
返回一个行为类似partial的新partialmethod描述符,除了它是用于方法定义,而不是直接调用。
func必须是一个descriptor或者可调用对象(两个对象都像常规函数一样作为descriptor)。
当func是一个descriptor(比如普遍的Python函数,classmethod(),staticmethod(),abstractmethod(),或者其它partialmethod实例时,get的调用会委托给底层的descriptor,并返回一个适当的partial对象。
当func不是可调用的descriptor时,会动态创建一个适当的绑定方法。用于方法时,该行为类似普通的Python函数:self参数会插入为第一个位置参数,甚至在传递给partialmethod构造器的args和keywords之前。
>>> class Cell(object):
... def __init__(self):
... self._alive = False
... @property
... def alive(self):
... return self._alive
... def set_state(self, state):
... self._alive = bool(state)
... set_alive = partialmethod(set_state, True)
... set_dead = partialmethod(set_state, False)
...
>>> c = Cell()
>>> c.alive
False
>>> c.set_alive()
>>> c.alive
True