lru_cache通过缓存函数结果提升性能,wraps保留被装饰函数的元信息以确保代码可维护性。两者在优化与调试中互补使用,适用于递归、I/O操作等重复计算场景,且需合理配置maxsize和typed参数以平衡性能与内存开销。

functools
lru_cache
wraps
lru_cache
wraps
在Python的日常开发中,我们总会遇到需要权衡性能与代码清晰度的问题。
functools
lru_cache
lru_cache
lru_cache
import time
from functools import lru_cache
@lru_cache(maxsize=128) # 默认缓存128个最近的调用
def expensive_calculation(a, b):
print(f"Calculating {a} + {b}...")
time.sleep(1) # 模拟耗时操作
return a + b
print(expensive_calculation(1, 2)) # 第一次计算
print(expensive_calculation(3, 4)) # 第二次计算
print(expensive_calculation(1, 2)) # 从缓存中获取
print(expensive_calculation(3, 4)) # 从缓存中获取运行这段代码,你会发现前两次调用有明显的延迟,而后两次几乎是瞬间返回,这就是
lru_cache
maxsize
而
wraps
__name__
__doc__
__module__
__annotations__
functools.wraps
from functools import wraps
def my_logging_decorator(func):
@wraps(func) # 关键在这里!
def wrapper(*args, **kwargs):
print(f"Calling function: {func.__name__} with args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"Function {func.__name__} finished. Result: {result}")
return result
return wrapper
@my_logging_decorator
def add(x, y):
"""This function adds two numbers."""
return x + y
print(add(5, 3))
print(f"Function name: {add.__name__}")
print(f"Function docstring: {add.__doc__}")如果没有
@wraps(func)
add.__name__
'wrapper'
add.__doc__
None
wrapper
'add'
'This function adds two numbers.'
wraps
lru_cache
lru_cache
lru_cache
最经典的例子就是递归函数,特别是那些带有重叠子问题(overlapping subproblems)的递归,比如计算斐波那契数列。没有缓存的斐波那契函数,其时间复杂度是指数级的,因为它会重复计算很多次相同的值。但只要加上一个
@lru_cache
@lru_cache(maxsize=None) # maxsize=None表示不限制缓存大小
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# print(fibonacci(30)) # 很快
# print(fibonacci.cache_info()) # 可以查看缓存命中率等信息其次,I/O密集型操作是
lru_cache
lru_cache
再者,计算密集型但输入有限或重复的函数也受益匪浅。比如,某个机器学习模型需要对输入数据进行复杂的预处理,如果这些预处理步骤对于相同的输入总是产生相同的结果,那么缓存这些结果就能避免不必要的重复计算。或者,在一些需要进行大量组合排列、穷举搜索的算法中,如果中间结果可以复用,
lru_cache
总的来说,当一个函数满足以下条件时,
lru_cache
functools.wraps
functools.wraps
wraps
Python的函数,不仅仅是一段可执行的代码,它还携带了丰富的元数据,比如
__name__
__doc__
__module__
__annotations__
__qualname__
当你创建一个装饰器时,通常会返回一个内部定义的
wrapper
@wraps(func)
__name__
wrapper
__doc__
wrapper
None
这会带来一系列问题:
wrapper
wraps
inspect
wrapper
help(decorated_function)
我曾经在一个项目中遇到过一个恼人的bug,一个第三方库在内部尝试通过
func.__name__
wraps
wraps
@wraps(func)
lru_cache
maxsize
typed
lru_cache
maxsize
typed
关于maxsize
maxsize
maxsize=None
0
maxsize=None
maxsize
maxsize
maxsize
lru_cache
cache_info()
hits
misses
maxsize
currsize
hits
misses
maxsize
misses
hits
maxsize
maxsize
关于typed
typed
typed=False
typed=False
lru_cache
f(1)
f(1.0)
1
1.0
process_data(1)
process_data(1.0)
typed=False
f(1)
f(1.0)
typed=False
typed=True
lru_cache
f(1)
f(1.0)
typed=True
int
str
typed=True
我的经验是,对于
maxsize
cache_info()
typed
1
1.0
typed=True
以上就是functools 模块中的 lru_cache 和 wraps的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号