python中functools 起什么作用

在 Python 中,functools 是一个标准库模块,提供了一组实用工具,用于操作函数和可调用对象。它常用于装饰器、函数缓存、部分应用等,帮助开发者编写更简洁和高效的代码。


functools 的作用和常用功能

以下是 functools 模块中几个常见功能的介绍及用法:


1. functools.partial

用于创建一个部分函数(partial function),即“固定”原函数的一些参数,生成一个新的函数。这样,调用新的函数时,只需提供未固定的参数。

用法示例
import functools

def 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

用于缓存函数的计算结果,以提升函数的性能,特别是对于需要重复调用的纯函数(即没有副作用的函数)。

用法示例
import functools

@functools.lru_cache(maxsize=128)  # 缓存最多 128 个结果
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

print(fib(10))  # 第一次计算需要时间
print(fib(10))  # 第二次直接从缓存中获取,速度很快
  • 参数说明
    • maxsize:缓存的最大条目数,设置为 None 表示无限缓存。
    • typed:如果为 True,会区分相同值的不同类型(如 11.0)。

3. functools.reduce

用于迭代地对序列的元素应用某个函数,并将结果累积到一个值。

用法示例
import functools

numbers = [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),可以根据第一个参数的类型调用不同的实现。

用法示例
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 的话,装饰器会使原函数的元信息丢失。

用法示例
import functools

def 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__)。

用法示例
import functools

@functools.total_ordering
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        return self.age == other.age

    def __lt__(self, other):
        return self.age < other.age

p1 = 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 限制,适用于缓存无限结果。

用法示例
import functools

@functools.cache
def factorial(n):
    return n * factorial(n-1) if n else 1

print(factorial(5))  # 第一次计算
print(factorial(5))  # 第二次从缓存中读取

总结

functools 模块是编写高效、优雅 Python 代码的强大工具箱,涵盖了函数缓存、部分函数、泛型函数、装饰器辅助工具等功能。熟练掌握这些功能,可以帮助你提升代码的可读性和性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥猪猪爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值