python | functools,一个非常有趣的 Python 库!

本文来源公众号“python”,仅用于学术分享,侵权删,干货满满。

原文链接:https://mp.weixin.qq.com/s/GWldmIiqUsMD1tYA3_KSyw

functools是Python标准库中专门用于高阶函数操作的模块,它为函数式编程提供了强大的工具支持。该库包含了一系列实用的函数和装饰器,能够帮助开发者创建偏函数、实现函数缓存、保留函数元信息等。functools的核心理念是"函数也是对象",通过对函数进行包装和转换,让代码更加简洁和高效。

安装

functools是Python标准库的一部分,从Python 2.5版本开始内置提供,无需额外安装。Python 3中functools功能更加完善,推荐使用Python 3.4及以上版本。

验证functools是否可用:

import functools
print(functools.__version__ if hasattr(functools, '__version__') else "已安装")
print(dir(functools))  # 查看所有可用功能

functools随Python解释器自动安装,可直接导入使用,无需任何配置。

核心特性:

  • 偏函数应用:通过partial固定函数的部分参数,创建新函数

  • 智能缓存机制:使用lru_cache装饰器自动缓存函数结果

  • 元信息保留:wraps装饰器保持被装饰函数的原始信息

  • 函数式工具:提供reduce等经典函数式编程函数

  • 性能优化:通过缓存和参数预设显著提升代码执行效率

  • 代码复用:简化重复代码,提高开发效率

基本功能

1、partial偏函数应用

在实际开发中,经常遇到需要多次调用同一个函数,但某些参数总是固定的情况。partial函数可以"冻结"部分参数,创建一个新的函数对象。

from functools import partial

# 原始函数
def power(base, exponent):
    return base ** exponent

# 创建平方函数(固定exponent=2)
square = partial(power, exponent=2)
print(square(5))  # 25
print(square(10)) # 100

# 创建立方函数
cube = partial(power, exponent=3)
print(cube(3))    # 27

2、lru_cache函数缓存

函数缓存是提升性能的重要手段,尤其适用于递归函数或需要重复计算的场景。lru_cache装饰器使用最近最少使用(LRU)算法自动缓存函数返回值,当使用相同参数调用函数时,直接返回缓存结果而不重新计算。

from functools import lru_cache

# 未使用缓存的斐波那契函数(效率低)
def fib_slow(n):
    if n < 2:
        return n
    return fib_slow(n-1) + fib_slow(n-2)

# 使用缓存的斐波那契函数(效率高)
@lru_cache(maxsize=128)
def fib_fast(n):
    if n < 2:
        return n
    return fib_fast(n-1) + fib_fast(n-2)

print(fib_fast(35))  # 9227465,速度极快
print(fib_fast.cache_info())  # 查看缓存统计信息

3、wraps保留函数元信息

当编写装饰器时,被装饰的函数会丢失原始的名称、文档字符串等元信息,这会影响调试和文档生成。wraps装饰器能够将原函数的元信息复制到包装函数上,保持函数签名的完整性。

from functools import wraps

def my_decorator(func):
    @wraps(func)  # 保留原函数信息
    def wrapper(*args, **kwargs):
        print(f"调用函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def greet(name):
    """向某人问候"""
    returnf"Hello, {name}!"

print(greet("Alice"))        # 调用函数: greet \n Hello, Alice!
print(greet.__name__)        # greet(保留了原函数名)
print(greet.__doc__)         # 向某人问候(保留了文档)

4、reduce累积计算

reduce函数是函数式编程的经典工具,它将一个二元函数累积地应用到序列的元素上,从左到右依次处理,最终返回单一结果。这个函数特别适合实现累加、累乘、查找最大最小值等聚合操作。

from functools import reduce

# 计算列表所有元素的乘积
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120

# 查找最大值
max_value = reduce(lambda x, y: x if x > y else y, [3, 7, 2, 9, 1])
print(max_value)  # 9

# 连接字符串
words = ['Python', 'is', 'awesome']
sentence = reduce(lambda x, y: x + ' ' + y, words)
print(sentence)  # Python is awesome

高级功能

1、total_ordering自动生成比较方法

在定义类时,如果要支持完整的比较操作(<, <=, >, >=, ==, !=),通常需要实现六个特殊方法,代码冗长且容易出错。total_ordering装饰器只需要实现__eq__和其中一个比较方法(如__lt__),就能自动生成其他所有比较方法。

from functools import total_ordering

@total_ordering
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def __eq__(self, other):
        return self.score == other.score
    
    def __lt__(self, other):
        return self.score < other.score

# 自动获得所有比较方法
s1 = Student("Alice", 85)
s2 = Student("Bob", 90)

print(s1 < s2)   # True
print(s1 <= s2)  # True
print(s1 > s2)   # False
print(s1 >= s2)  # False

2、singledispatch单分派泛函数

Python原生不支持函数重载,但singledispatch提供了基于类型的函数分派机制。通过这个装饰器,可以为同一个函数根据第一个参数的类型注册不同的实现版本。

from functools import singledispatch

@singledispatch
def process(data):
    """默认处理方法"""
    print(f"处理未知类型: {type(data)}")

@process.register(int)
def _(data):
    print(f"处理整数: {data * 2}")

@process.register(str)
def _(data):
    print(f"处理字符串: {data.upper()}")

@process.register(list)
def _(data):
    print(f"处理列表: {len(data)} 个元素")

# 根据类型自动分派
process(42)           # 处理整数: 84
process("hello")      # 处理字符串: HELLO
process([1, 2, 3])    # 处理列表: 3 个元素

总结

functools库是Python函数式编程的核心工具箱,提供了一系列强大而实用的高阶函数工具。通过partial偏函数可以简化重复参数传递,lru_cache缓存机制能显著提升递归和重复计算的性能,wraps确保装饰器不破坏函数元信息,reduce实现优雅的累积计算,高级功能如total_ordering简化类的比较方法定义,singledispatch提供了基于类型的函数重载能力。这些工具不仅能让代码更简洁易读,还能在API请求优化、数据处理管道等实际场景中发挥重要作用。

THE END !

文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值