本文目录导读:

- 使用
@lru_cache装饰器(内置支持) - 使用
@cache装饰器(Python 3.9+) - 自定义 LRU 缓存类
- 使用第三方库
cachetools - 基于字典的简单限制
- 装饰器版本的限制缓存
- 选择建议
在Python中限制单类缓存存储数量有多种实现方式,以下是几种常见方法:
使用 @lru_cache 装饰器(内置支持)
from functools import lru_cache
@lru_cache(maxsize=128) # 限制缓存最多存储128个结果
def expensive_function(n):
# 模拟耗时计算
return n * 2
# 使用示例
print(expensive_function(10))
print(expensive_function.cache_info()) # 查看缓存统计信息
使用 @cache 装饰器(Python 3.9+)
from functools import cache
@cache # 无限制缓存,但可以用其他方式清空
def my_function(x):
return x ** 2
# 手动清空缓存
my_function.cache_clear()
自定义 LRU 缓存类
from collections import OrderedDict
import time
class LRUCache:
def __init__(self, maxsize=100):
self.maxsize = maxsize
self.cache = OrderedDict()
self.access_times = {}
def get(self, key):
if key in self.cache:
# 更新访问时间
self.access_times[key] = time.time()
self.cache.move_to_end(key)
return self.cache[key]
return None
def set(self, key, value):
if key in self.cache:
self.cache[key] = value
self.access_times[key] = time.time()
self.cache.move_to_end(key)
else:
if len(self.cache) >= self.maxsize:
# 移除最久未使用的项目
oldest_key = next(iter(self.cache))
del self.cache[oldest_key]
del self.access_times[oldest_key]
self.cache[key] = value
self.access_times[key] = time.time()
def __contains__(self, key):
return key in self.cache
# 使用示例
cache = LRUCache(maxsize=3)
cache.set('a', 1)
cache.set('b', 2)
cache.set('c', 3)
print(cache.get('a')) # 访问 'a'
cache.set('d', 4) # 'b' 被移除
print('b' in cache) # False
使用第三方库 cachetools
首先安装:pip install cachetools
from cachetools import LRUCache, TTLCache
# LRU缓存
lru_cache = LRUCache(maxsize=100)
# 带过期时间的缓存
ttl_cache = TTLCache(maxsize=100, ttl=3600) # 1小时过期
# 使用示例
lru_cache['key1'] = 'value1'
print(lru_cache.get('key1'))
基于字典的简单限制
class SimpleCache:
def __init__(self, maxsize=100):
self.maxsize = maxsize
self.cache = {}
self.order = [] # 记录添加顺序
def store(self, key, value):
if key in self.cache:
self.cache[key] = value
self.order.remove(key)
self.order.append(key)
else:
while len(self.cache) >= self.maxsize:
# 移除最旧的元素
oldest_key = self.order.pop(0)
del self.cache[oldest_key]
self.cache[key] = value
self.order.append(key)
def retrieve(self, key):
if key in self.cache:
# 更新顺序(LRU风格)
self.order.remove(key)
self.order.append(key)
return self.cache[key]
return None
# 使用示例
cache = SimpleCache(maxsize=3)
cache.store('a', 1)
cache.store('b', 2)
cache.store('c', 3)
print(cache.retrieve('a')) # 1
装饰器版本的限制缓存
from functools import wraps
from collections import OrderedDict
def limited_cache(maxsize=100):
def decorator(func):
cache = OrderedDict()
@wraps(func)
def wrapper(*args, **kwargs):
key = (args, tuple(kwargs.items()))
if key in cache:
cache.move_to_end(key)
return cache[key]
result = func(*args, **kwargs)
if len(cache) >= maxsize:
cache.popitem(last=False) # 移除最旧的
cache[key] = result
return result
wrapper.cache_clear = cache.clear
wrapper.cache_info = lambda: {
'size': len(cache),
'maxsize': maxsize
}
return wrapper
return decorator
# 使用示例
@limited_cache(maxsize=50)
def expensive_calculation(x):
return x ** 3
选择建议
- 标准库方式:优先使用
functools.lru_cache,内置支持,性能好 - 需要过期时间:使用
cachetools库 - 完全自定义:实现自己的缓存类
- 简单场景:使用内置字典加计数器
注意事项:
- 缓存过大可能消耗大量内存
- 考虑线程安全(如有并发访问需求)
- 缓存对象需要可哈希(hashable)
- 注意缓存对象的生命周期管理