Python functools模块核心功能详解:partial、lru_cache与singledispatch
本文深入解析Python标准库functools模块的核心功能。重点介绍partial如何创建偏函数以简化参数调用,lru_cache装饰器如何通过内存缓存提升重复计算性能,以及singledispatch如何实现基于类型的泛型函数分发。同时涵盖update_wrapper和wraps在装饰器开发中保留元数据的作用,结合代码示例说明各函数的具体用法与注意事项。
partial
该工具用于构建偏函数,即将默认参数绑定到可调用对象上,最终返回一个新的可调用对象。
通过固定原函数的部分参数,偏函数能够简化后续的调用过程,使代码更加简洁。
from functools import partial
int2 = partial(int, base=8)
print(int2('123'))
# 83update_wrapper
使用partial包装后的函数默认不包含__name__和__doc__等属性。
update_wrapper的主要作用是将被包装函数的__name__等元数据属性复制到新的函数对象中,以保持函数信息的完整性。
from functools import update_wrapper
def wrap2(func):
def inner(*args):
return func(*args)
return update_wrapper(inner, func)
@wrap2
def demo():
print('hello world')
print(demo.__name__)
# demowraps
wraps函数旨在装饰器中自动拷贝被装饰函数的__name__属性,确保调试和文档生成的准确性。
它实际上是对update_wrapper功能的高级封装,简化了装饰器的编写过程。
from functools import wraps
def wrap1(func):
@wraps(func) # 去掉就会返回inner
def inner(*args):
print(func.__name__)
return func(*args)
return inner
@wrap1
def demo():
print('hello world')
print(demo.__name__)
# demoreduce
在Python2中,该函数等同于内建函数reduce。
其核心功能是将一个序列通过累积操作归纳为单一的输出结果。
reduce(function, sequence, startValue)
from functools import reduce
l = range(1,50)
print(reduce(lambda x,y:x+y, l))
# 1225cmp_to_key
在list.sort方法和内建函数sorted中均提供了key参数用于指定排序依据。
x = ['hello','worl','ni']
x.sort(key=len)
print(x)
# ['ni', 'worl', 'hello']在Python3之前的版本中,还曾提供cmp参数用于直接比较两个元素的大小。
cmp_to_key函数的作用是将旧式的比较函数转换为适用于key参数的键函数,以兼容新版排序机制。
lru_cache
该功能允许对函数的返回值进行快速缓存或清除缓存操作。
作为装饰器使用时,它能缓存函数的调用结果。对于参数固定且需多次调用的函数,利用此装饰器可显著加速程序运行。
由于该装饰器会将不同的调用结果存储在内存中,因此在实际应用中需关注内存占用情况,合理设置缓存大小。
from functools import lru_cache
@lru_cache(maxsize=30) # maxsize参数告诉lru_cache缓存最近多少个返回值
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print([fib(n) for n in range(10)])
fib.cache_clear() # 清空缓存singledispatch
单分发器是Python3.4新增的功能,专门用于实现泛型函数。
它根据单一参数的具体类型,动态判断并调用对应的处理函数,从而实现多态行为。
from functools import singledispatch
@singledispatch
def fun(text):
print('String:' + text)
@fun.register(int)
def _(text):
print(text)
@fun.register(list)
def _(text):
for k, v in enumerate(text):
print(k, v)
@fun.register(float)
@fun.register(tuple)
def _(text):
print('float, tuple')
fun('i am is hubo')
fun(123)
fun(['a','b','c'])
fun(1.23)
print(fun.registry) # 所有的泛型函数
print(fun.registry[int]) # 获取int的泛型函数
# String:i am is hubo
# 123
# 0 a
# 1 b
# 2 c
# float, tuple
# {<class 'object'>: <function fun at 0x106d10f28>, <class 'int'>: <function _ at 0x106f0b9d8>, <class 'list'>: <function _ at 0x106f0ba60>, <class 'tuple'>: <function _ at 0x106f0bb70>, <class 'float'>: <function _ at 0x106f0bb70>}
# <function _ at 0x106f0b9d8>以上内容为个人经验分享,旨在提供参考,欢迎读者支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













