Python functools模块核心功能详解:partial、lru_cache与singledispatch

Miles
Miles
发布时间:2026-10-15 | 3人浏览过
原创

本文深入解析Python标准库functools模块的核心功能。重点介绍partial如何创建偏函数以简化参数调用,lru_cache装饰器如何通过内存缓存提升重复计算性能,以及singledispatch如何实现基于类型的泛型函数分发。同时涵盖update_wrapper和wraps在装饰器开发中保留元数据的作用,结合代码示例说明各函数的具体用法与注意事项。

partial

该工具用于构建偏函数,即将默认参数绑定到可调用对象上,最终返回一个新的可调用对象。

通过固定原函数的部分参数,偏函数能够简化后续的调用过程,使代码更加简洁。

from functools import partial

int2 = partial(int, base=8)
print(int2('123'))
# 83

update_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__)
# demo

wraps

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__)
# demo

reduce

在Python2中,该函数等同于内建函数reduce。

其核心功能是将一个序列通过累积操作归纳为单一的输出结果。

reduce(function, sequence, startValue)

from functools import reduce

l = range(1,50)
print(reduce(lambda x,y:x+y, l))
# 1225

cmp_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>

以上内容为个人经验分享,旨在提供参考,欢迎读者支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表