Python —— 好玩的functools

Python —— 好玩的functools
最新回答
听萧与声

2026-10-23 14:36:49

Python 的 functools 模块是一个强大的工具库,提供了许多用于函数式编程和高阶函数操作的工具。其中,partial 类是一个非常实用的功能,它允许你固定部分参数,从而创建一个新的可调用对象(即“偏函数”)。以下是对 partial 的详细解析:

1. partial 的核心作用

partial 通过“冻结”函数的部分参数,生成一个新的可调用对象。这在以下场景中特别有用:

  • 简化重复调用:当某个函数需要反复传入相同的参数时,可以预先固定这些参数。
  • 适配接口:将多参数函数转换为少参数函数,以适配其他函数的输入要求。
示例代码:from functools import partialdef multiply(x, y): return x * y# 创建一个偏函数,固定 y=2double = partial(multiply, y=2)print(double(5)) # 输出: 10 (相当于 multiply(5, 2))2. partial 的底层实现

通过 __slots__ 可以看到 partial 类的属性:

  • func: 原始函数对象。
  • args: 固定的位置参数(元组形式)。
  • keywords: 固定的关键字参数(字典形式)。
  • __dict__ 和 __weakref__: 用于支持动态属性和弱引用。
关键点:
  • partial 是一个类,而非函数,它通过 __new__ 或 __init__ 存储原始函数和参数。
  • 调用偏函数时,实际会合并预先固定的参数和调用时传入的参数,再传递给原始函数。
3. partial 的实际应用场景(1) 简化函数调用import operator# 固定 operator.add 的第一个参数为 10add_ten = partial(operator.add, 10)print(add_ten(5)) # 输出: 15 (10 + 5)(2) 适配高阶函数from functools import partial# 将 print 函数的 sep 参数固定为 ", "custom_print = partial(print, sep=", ")custom_print("A", "B", "C") # 输出: A, B, C(3) 与 map/filter 结合numbers = [1, 2, 3, 4]# 固定 pow 的第二个参数为 2(计算平方)square = partial(pow, y=2)squared_numbers = list(map(square, numbers)) # 输出: [1, 4, 9, 16]4. 注意事项
  • 参数顺序:partial 固定的参数会优先于调用时传入的参数。例如:def func(a, b, c): return a + b + cnew_func = partial(func, 1, c=3)print(new_func(b=2)) # 输出: 6 (a=1, b=2, c=3)
  • 不可变参数:partial 不会修改原始函数,而是返回一个新对象。
  • 性能开销:偏函数调用会略微增加一层间接性,但对大多数场景影响可忽略。
5. 对比 lambda

partial 和 lambda 都能实现类似功能,但 partial 更清晰且支持 __doc__ 等属性:

# 使用 lambdadouble_lambda = lambda x: multiply(x, 2)# 使用 partialdouble_partial = partial(multiply, y=2)# partial 保留了原始函数的元信息print(double_partial.__name__) # 输出: multiply总结

functools.partial 是一个轻量级但强大的工具,通过固定部分参数将复杂函数转换为更简单的形式。它的核心在于参数绑定和代码复用,尤其适合需要频繁调用相似参数的场景。结合 __slots__ 的设计,partial 在保证灵活性的同时优化了内存使用。