functools模块
functools模块概述
functools模块提供了用于处理函数的高阶操作,是函数式编程的重要工具。
lru_cache - 缓存装饰器
lru_cache是一个装饰器,用于缓存函数的返回结果,提高性能。
from functools import lru_cache
# 基本用法
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# 使用
print(fibonacci(50)) # 输出: 12586269025
print(fibonacci.cache_info()) # 查看缓存信息
# 清除缓存
fibonacci.cache_clear()
缓存信息
@lru_cache(maxsize=10)
def expensive_function(x):
print(f"计算 {x}...")
return x * x
# 第一次调用
expensive_function(5)
# 输出: 计算 5...
# 第二次调用(使用缓存)
expensive_function(5)
# 不输出任何内容
# 查看缓存信息
print(expensive_function.cache_info())
# 输出: CacheInfo(hits=1, misses=1, maxsize=10, currsize=1)
partial - 偏函数
partial用于创建一个新函数,固定原函数的部分参数。
from functools import partial
# 基本用法
def power(base, exponent):
return base ** exponent
# 创建平方函数
square = partial(power, exponent=2)
print(square(5)) # 输出: 25
# 创建立方函数
cube = partial(power, exponent=3)
print(cube(5)) # 输出: 125
# 实际应用:排序
from operator import itemgetter
students = [
{'name': 'Alice', 'age': 25, 'score': 90},
{'name': 'Bob', 'age': 22, 'score': 85},
{'name': 'Charlie', 'age': 23, 'score': 92}
]
# 按年龄排序
sort_by_age = partial(sorted, key=itemgetter('age'))
sorted_students = sort_by_age(students)
print([s['name'] for s in sorted_students])
# 输出: ['Bob', 'Charlie', 'Alice']
reduce - 归约函数
reduce将一个函数应用于序列的所有元素,累积结果。
from functools import reduce
# 基本用法
numbers = [1, 2, 3, 4, 5]
# 求和
total = reduce(lambda a, b: a + b, numbers)
print(total) # 输出: 15
# 求积
product = reduce(lambda a, b: a * b, numbers)
print(product) # 输出: 120
# 实际应用:扁平化嵌套列表
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = reduce(lambda a, b: a + b, nested)
print(flattened) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 实际应用:合并字典
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict3 = {'e': 5, 'f': 6}
merged = reduce(lambda a, b: {**a, **b}, [dict1, dict2, dict3])
print(merged)
# 输出: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
wraps - 函数包装
wraps用于保留被装饰函数的元信息。
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
"""包装器文档字符串"""
print("装饰器执行前")
result = func(*args, **kwargs)
print("装饰器执行后")
return result
return wrapper
@my_decorator
def say_hello(name):
"""向某人打招呼"""
print(f"Hello, {name}!")
# 使用
say_hello("Alice")
# 查看函数信息
print(say_hello.__name__) # 输出: say_hello
print(say_hello.__doc__) # 输出: 向某人打招呼
# 没有@wraps时,__name__会是'wrapper'
其他实用函数
total_ordering - 自动比较方法
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", 90)
s2 = Student("Bob", 85)
print(s1 > s2) # 输出: True
print(s1 >= s2) # 输出: True
print(s1 <= s2) # 输出: False
singledispatch - 单分派泛型函数
from functools import singledispatch
@singledispatch
def process(value):
raise NotImplementedError(f"Unsupported type: {type(value)}")
@process.register(int)
def _(value):
return f"Processing integer: {value}"
@process.register(str)
def _(value):
return f"Processing string: {value}"
@process.register(list)
def _(value):
return f"Processing list with {len(value)} items"
# 使用
print(process(42)) # 输出: Processing integer: 42
print(process("hello")) # 输出: Processing string: hello
print(process([1, 2, 3])) # 输出: Processing list with 3 items
cached_property - 缓存属性
from functools import cached_property
class DataAnalyzer:
def __init__(self, data):
self.data = data
@cached_property
def mean(self):
"""计算平均值(只计算一次)"""
print("计算平均值...")
return sum(self.data) / len(self.data)
@cached_property
def std_dev(self):
"""计算标准差(只计算一次)"""
print("计算标准差...")
mean = self.mean # 使用缓存的mean
return (sum((x - mean) ** 2 for x in self.data) / len(self.data)) ** 0.5
# 使用
analyzer = DataAnalyzer([1, 2, 3, 4, 5])
print(analyzer.mean) # 输出: 计算平均值... 3.0
print(analyzer.mean) # 输出: 3.0(不重新计算)
print(analyzer.std_dev) # 输出: 计算标准差... 1.414...
实际应用案例
1. 函数缓存
from functools import lru_cache
import time
@lru_cache(maxsize=None)
def fibonacci_optimized(n):
"""优化的斐波那契数列"""
if n < 2:
return n
return fibonacci_optimized(n-1) + fibonacci_optimized(n-2)
# 测试性能
start = time.time()
result = fibonacci_optimized(100)
elapsed = time.time() - start
print(f"结果: {result}")
print(f"耗时: {elapsed:.6f}秒")
2. 函数组合
from functools import reduce
def compose(*functions):
"""函数组合"""
return reduce(lambda f, g: lambda x: f(g(x)), functions)
# 使用
def add_one(x):
return x + 1
def multiply_by_two(x):
return x * 2
def square(x):
return x ** 2
# 创建组合函数
transform = compose(square, multiply_by_two, add_one)
print(transform(3)) # 输出: 64 ((3+1)*2)^2
3. 配置工厂
from functools import partial
def create_validator(min_length=None, max_length=None, pattern=None):
"""创建验证器"""
def validate(value):
if min_length and len(value) < min_length:
return False
if max_length and len(value) > max_length:
return False
if pattern:
import re
if not re.match(pattern, value):
return False
return True
return validate
# 创建不同类型的验证器
username_validator = create_validator(min_length=3, max_length=20)
password_validator = create_validator(min_length=8, pattern=r'^[a-zA-Z0-9]+$')
print(username_validator("ab")) # 输出: False
print(username_validator("alice")) # 输出: True
print(password_validator("pass123")) # 输出: False
print(password_validator("pass1234")) # 输出: True
性能优化
import time
from functools import lru_cache
# 不使用缓存
def fibonacci_no_cache(n):
if n < 2:
return n
return fibonacci_no_cache(n-1) + fibonacci_no_cache(n-2)
# 使用缓存
@lru_cache(maxsize=None)
def fibonacci_with_cache(n):
if n < 2:
return n
return fibonacci_with_cache(n-1) + fibonacci_with_cache(n-2)
# 测试性能
n = 30
start = time.time()
result1 = fibonacci_no_cache(n)
time1 = time.time() - start
start = time.time()
result2 = fibonacci_with_cache(n)
time2 = time.time() - start
print(f"无缓存: {time1:.4f}秒")
print(f"有缓存: {time2:.6f}秒")
print(f"加速比: {time1/time2:.0f}倍")
最佳实践
- 使用
lru_cache优化递归函数和重复计算 - 使用
partial创建专用函数 - 使用
reduce进行累积操作 - 使用
wraps保留装饰函数的元信息 - 考虑使用
total_ordering简化比较方法 - 使用
singledispatch实现类型分派
functools模块是Python函数式编程的重要工具,掌握它们能让你的代码更加高效和优雅。