好的,我们再详细讲解functools
模块的常用工具,包括每个API的语法和参数,并特别详细解释lru_cache
的工作原理及其缓存机制。
functools
简介
functools
模块提供了许多高阶函数和工具,用于操作或返回其他函数,帮助我们更方便地进行函数式编程。
1. partial
函数
partial
函数用于固定函数的部分参数,并返回一个新的函数。
语法
functools.partial(func, /, *args, **keywords)
参数说明
func
:要调用的函数。*args
:固定的参数,可以是多个。**keywords
:固定的关键字参数,可以是多个。
示例
from functools import partial
def add(a, b, c):
return a + b + c
# 固定参数a为1
add1 = partial(add, 1)
# 调用新函数
print(add1(2, 3)) # 输出 6
在这个例子中,partial(add, 1)
创建了一个新函数 add1
,它的第一个参数永远是1。
2. lru_cache
装饰器
lru_cache
用于缓存函数的结果,以提高性能。LRU是“Least Recently Used”的缩写,即最近最少使用缓存策略。这意味着如果缓存达到最大容量,最久未使用的缓存条目会被移除。
语法
functools.lru_cache(maxsize=128, typed=False)
参数说明
maxsize
:缓存的最大条目数。超过这个数量时,最近最少使用的条目将被移除。如果设置为None
,缓存大小无限。typed
:如果为True
,不同类型的参数将分别缓存。例如,f(3)
和f(3.0)
会被视为不同的调用并分别缓存。
示例
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(10)) # 输出 55
通过使用lru_cache
装饰器,函数fibonacci
的结果将被缓存,避免重复计算。缓存没有自动失效机制,但可以通过设置合理的maxsize
来控制缓存大小。
3. cmp_to_key
函数
cmp_to_key
用于将旧式的比较函数转换为键函数,以便与Python的排序函数一起使用。
语法
functools.cmp_to_key(func)
参数说明
func
:一个旧式的比较函数,该函数接受两个参数并返回一个负数、零或正数,分别表示小于、等于或大于。
示例
from functools import cmp_to_key
def compare_length(s1, s2):
return len(s1) - len(s2)
strings = ["apple", "banana", "cherry", "date"]
sorted_strings = sorted(strings, key=cmp_to_key(compare_length))
print(sorted_strings) # 输出 ['date', 'apple', 'banana', 'cherry']
在这个例子中,cmp_to_key
将比较函数compare_length
转换为键函数,用于sorted
函数的排序。
4. wraps
装饰器
wraps
用于编写装饰器时,保留被装饰函数的元数据,例如函数名和文档字符串。
语法
functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
参数说明
wrapped
:被装饰的函数。assigned
:一个元组,指定要复制的属性,默认值是('__module__', '__name__', '__qualname__', '__doc__', '__annotations__')
。updated
:一个元组,指定要更新的属性,默认值是('__dict__',)
。
示例
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} 执行时间: {end_time - start_time} 秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(2)
print("函数执行完毕")
slow_function()
在这个例子中,wraps
确保了slow_function
保留其原始的元数据,例如函数名和文档字符串。
应用场景和总结
partial
:通过固定函数的部分参数创建新函数,简化函数调用,适用于重复调用某些参数固定的函数场景。lru_cache
:缓存函数结果,提高性能,适用于计算量大且结果重复的函数。缓存采用LRU策略,没有自动失效机制,但可以通过合理设置maxsize
控制缓存大小。cmp_to_key
:将旧式比较函数转换为键函数,适用于需要自定义排序规则的场景。wraps
:编写装饰器时保留被装饰函数的元数据,确保装饰后的函数仍然保留原始属性,适用于任何需要装饰器的场景。
通过这些工具,我们可以编写出更简洁、高效、可读性更强的代码。