functools模块
全部方法
__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