Python functools 函数工具

1 min入门

Python functools 函数工具 的完整教学讲解。

reduce 归约

基本写法:reduce 归约 functools.reduce(<函数>, <可迭代>, [初始值])

# 累积应用函数到所有元素
from functools import reduce
import operator
result = reduce(operator.add, [1, 2, 3, 4], 0)  # 10

基本写法:reduce 求最大值 functools.reduce(lambda a, b: a if a > b else b, <可迭代>)

# 找出最大值
from functools import reduce
nums = [3, 1, 4, 1, 5, 9]
m = reduce(lambda a, b: a if a > b else b, nums)  # 9

缓存装饰器

基本写法:lru_cache LRU 缓存 @lru_cache(maxsize=<大小>)

# 基于最近最少使用策略的缓存
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

基本写法:cache 无限缓存 @cache

# Python 3.9+ 无大小限制的缓存
from functools import cache
@cache
def slow_query(key):
    return database.get(key)

基本写法:查看缓存信息 <函数>.cache_info()

# 查看缓存命中情况
fibonacci(50)
print(fibonacci.cache_info())
# CacheInfo(hits=49, misses=51, maxsize=128, currsize=51)

基本写法:清除缓存 <函数>.cache_clear()

# 手动清空缓存
fibonacci.cache_clear()

基本写法:Python 3.9+ typed 参数类型区分 @lru_cache(typed=True)

# 区分不同参数类型(1 和 1.0 分别缓存)
from functools import lru_cache
@lru_cache(typed=True)
def f(x):
    return x * 2

partial 偏函数

基本写法:创建偏函数 functools.partial(<函数>, *<参数>, **<关键字参数>)

# 固定部分参数生成新函数
from functools import partial
int2 = partial(int, base=2)
print(int2("1010"))  # 10

基本写法:固定位置参数 functools.partial(<函数>, <值>)

# 固定第一个参数
from functools import partial
def power(base, exp):
    return base ** exp
square = partial(power, exp=2)
print(square(5))  # 25

基本写法:partial 对象属性 <偏函数>.args / .keywords

# 查看偏函数固定的参数
p = partial(int, base=2)
print(p.args)      # ()
print(p.keywords)  # {'base': 2}

wraps 保留元信息

基本写法:使用 @wraps @wraps(<原函数>)

# 装饰器中保留原函数元信息
from functools import wraps
def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

singledispatch 单分派

基本写法: singledispatch 按类型分派 @singledispatch

# 根据第一个参数类型调用不同实现
from functools import singledispatch
@singledispatch
def process(data):
    raise TypeError(f"不支持类型: {type(data)}")

@process.register
def _(data: int):
    return f"整数: {data}"

基本写法:注册分派函数 @<函数>.register

# 注册字符串类型处理
@process.register
def _(data: str):
    return f"字符串: {data}"

基本写法:注册多个类型 @<函数>.register(<类型1>, <类型2>)

# 一个实现处理多种类型
@process.register(list)
@process.register(tuple)
def _(data):
    return f"序列: {len(data)} 项"

singledispatchmethod 方法分派

基本写法: singledispatchmethod 类方法分派 @singledispatchmethod

# Python 3.8+ 类方法按参数类型分派
from functools import singledispatchmethod
class Processor:
    @singledispatchmethod
    def process(self, data):
        raise TypeError("不支持")
    @process.register
    def _from_int(self, data: int):
        return data * 2

total_ordering 自动补全比较方法

换行写法:total_ordering 装饰类 @total_ordering class <类名>: def __eq__(self, other): ... def __lt__(self, other): ...

# 定义一个比较方法后自动生成其余
from functools import total_ordering
@total_ordering
class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade
    def __eq__(self, other):
        return self.grade == other.grade
    def __lt__(self, other):
        return self.grade < other.grade

cached_property 缓存属性

基本写法:cached_property @cached_property

# 属性计算结果缓存,只计算一次
from functools import cached_property
class DataSet:
    def __init__(self, data):
        self.data = data
    @cached_property
    def mean(self):
        return sum(self.data) / len(self.data)

cmp_to_key 比较函数转键

基本写法:cmp_to_key 转换比较函数 functools.cmp_to_key(<比较函数>)

# 将旧式比较函数转为 key 函数
from functools import cmp_to_key
def compare(a, b):
    if a < b:
        return -1
    elif a > b:
        return 1
    return 0
sorted([3, 1, 2], key=cmp_to_key(compare))

Python 3.13+ functools 增强

基本写法:Python 3.13+ lru_cache 不带参数 @lru_cache

# Python 3.13+ lru_cache 无参数时等同于 cache
from functools import lru_cache
@lru_cache
def compute(x):
    return x * x

基本写法:Python 3.13+ singledispatch 泛型方法 @singledispatchmethod

# Python 3.13+ 支持联合类型注册
from functools import singledispatch
@singledispatch
def handle(data):
    pass
@handle.register(int | float)
def _(data):
    return data * 2