在 Python 中,functools
是一个标准库模块,提供了一组实用工具,用于操作函数和可调用对象。它常用于装饰器、函数缓存、部分应用等,帮助开发者编写更简洁和高效的代码。
functools
的作用和常用功能
以下是 functools
模块中几个常见功能的介绍及用法:
1. functools.partial
用于创建一个部分函数(partial function),即“固定”原函数的一些参数,生成一个新的函数。这样,调用新的函数时,只需提供未固定的参数。
用法示例
python">import functoolsdef power(base, exponent):return base ** exponent# 固定 exponent=2
square = functools.partial(power, exponent=2)
print(square(4)) # 相当于 power(4, 2),输出 16# 固定 base=2
cube = functools.partial(power, base=2)
print(cube(3)) # 相当于 power(2, 3),输出 8
2. functools.lru_cache
用于缓存函数的计算结果,以提升函数的性能,特别是对于需要重复调用的纯函数(即没有副作用的函数)。
用法示例
python">import functools@functools.lru_cache(maxsize=128) # 缓存最多 128 个结果
def fib(n):if n < 2:return nreturn fib(n-1) + fib(n-2)print(fib(10)) # 第一次计算需要时间
print(fib(10)) # 第二次直接从缓存中获取,速度很快
- 参数说明:
maxsize
:缓存的最大条目数,设置为None
表示无限缓存。typed
:如果为True
,会区分相同值的不同类型(如1
和1.0
)。
3. functools.reduce
用于迭代地对序列的元素应用某个函数,并将结果累积到一个值。
用法示例
python">import functoolsnumbers = [1, 2, 3, 4]
result = functools.reduce(lambda x, y: x * y, numbers)
print(result) # 相当于 (((1*2)*3)*4),输出 24
4. functools.singledispatch
实现单分派泛型函数(single-dispatch generic function),可以根据第一个参数的类型调用不同的实现。
用法示例
python">import functools@functools.singledispatch
def process(value):print(f"Default processing for {value}")@process.register(int)
def _(value: int):print(f"Processing an integer: {value}")@process.register(str)
def _(value: str):print(f"Processing a string: {value}")process(42) # 调用 int 版本
process("hello") # 调用 str 版本
process(3.14) # 调用默认版本
5. functools.wraps
用于编写装饰器时保留被装饰函数的元信息(如函数名 __name__
和文档字符串 __doc__
)。
问题背景
不使用 functools.wraps
的话,装饰器会使原函数的元信息丢失。
用法示例
python">import functoolsdef my_decorator(func):@functools.wraps(func) # 保留原函数的元信息def wrapper(*args, **kwargs):print("Calling decorated function")return func(*args, **kwargs)return wrapper@my_decorator
def say_hello():"""This function says hello."""print("Hello!")say_hello()
print(say_hello.__name__) # 输出 "say_hello",而不是 "wrapper"
print(say_hello.__doc__) # 输出 "This function says hello."
6. functools.total_ordering
简化实现比较运算符。只需要实现 __eq__
和一个其他比较方法(如 __lt__
),total_ordering
会自动生成其他方法(如 __le__
、__gt__
和 __ge__
)。
用法示例
python">import functools@functools.total_ordering
class Person:def __init__(self, name, age):self.name = nameself.age = agedef __eq__(self, other):return self.age == other.agedef __lt__(self, other):return self.age < other.agep1 = Person("Alice", 30)
p2 = Person("Bob", 25)
print(p1 > p2) # True
print(p1 <= p2) # False
7. functools.cache
从 Python 3.9 开始,cache
是一种更简单的 lru_cache
变体,没有 maxsize
限制,适用于缓存无限结果。
用法示例
python">import functools@functools.cache
def factorial(n):return n * factorial(n-1) if n else 1print(factorial(5)) # 第一次计算
print(factorial(5)) # 第二次从缓存中读取
总结
functools
模块是编写高效、优雅 Python 代码的强大工具箱,涵盖了函数缓存、部分函数、泛型函数、装饰器辅助工具等功能。熟练掌握这些功能,可以帮助你提升代码的可读性和性能。