本文目录导读:

在Python中限制缓存最大占用空间,有几种常见的方法,我来介绍几个实用的方案:
使用 cachetools 库(推荐)
cachetools 提供了基于大小限制的缓存实现:
from cachetools import LRUCache
import sys
# 创建最大容量为100个元素的LRU缓存
cache = LRUCache(maxsize=100)
# 或者更精确地限制内存使用
class SizeLimitedCache:
def __init__(self, max_size_mb=100):
self.max_size = max_size_mb * 1024 * 1024 # 转换为字节
self.cache = {}
self.current_size = 0
def add(self, key, value):
# 计算新对象大小
obj_size = sys.getsizeof(value)
# 如果单个对象超过限制,拒绝存储
if obj_size > self.max_size:
raise ValueError("对象太大,无法缓存")
# 腾出空间
while self.current_size + obj_size > self.max_size and self.cache:
self._evict_oldest()
self.cache[key] = value
self.current_size += obj_size
def _evict_oldest(self):
if self.cache:
oldest_key = next(iter(self.cache))
old_value = self.cache.pop(oldest_key)
self.current_size -= sys.getsizeof(old_value)
# 使用示例
cache = SizeLimitedCache(max_size_mb=50)
cache.add("large_data", b"x" * 1000000) # 1MB数据
使用 functools.lru_cache
Python内置的LRU缓存,按条目数限制:
from functools import lru_cache
@lru_cache(maxsize=100) # 最多缓存100个结果
def expensive_function(n):
# 模拟耗时计算
result = n * n
return result
# 使用
print(expensive_function(42)) # 计算结果并缓存
print(expensive_function(42)) # 直接从缓存获取
# 查看缓存信息
print(expensive_function.cache_info())
# CacheInfo(hits=1, misses=1, maxsize=100, currsize=1)
基于磁盘的缓存限制
使用 diskcache 库实现磁盘缓存空间限制:
# 安装: pip install diskcache
import diskcache as dc
# 创建磁盘缓存,限制最大大小为1GB
cache = dc.Cache('/tmp/my_cache', size_limit=1_000_000_000) # 1GB
# 使用
cache.set('key1', 'value1')
cache.set('key2', 'value2')
# 获取缓存大小
print(f"当前缓存大小: {cache.volume()} bytes")
自定义内存管理方案
更精确的内存控制:
import sys
import time
from collections import OrderedDict
class SmartMemoryCache:
def __init__(self, max_size_bytes=500*1024*1024): # 默认500MB
self.max_size = max_size_bytes
self.cache = OrderedDict()
self.current_size = 0
def _estimate_size(self, obj):
"""估算对象大小"""
if isinstance(obj, (int, float, bool)):
return sys.getsizeof(obj)
elif isinstance(obj, str):
return sys.getsizeof(obj) + len(obj.encode('utf-8'))
elif isinstance(obj, bytes):
return sys.getsizeof(obj) + len(obj)
elif isinstance(obj, (list, tuple, set)):
size = sys.getsizeof(obj)
for item in obj:
size += self._estimate_size(item)
return size
elif isinstance(obj, dict):
size = sys.getsizeof(obj)
for k, v in obj.items():
size += self._estimate_size(k) + self._estimate_size(v)
return size
else:
return sys.getsizeof(obj)
def set(self, key, value, ttl=None):
"""设置缓存,支持TTL"""
obj_size = self._estimate_size(value)
# 单个对象超出限制
if obj_size > self.max_size:
print(f"警告:对象大小 {obj_size} 超过缓存限制")
return False
# 如果键已存在,先释放空间
if key in self.cache:
self.current_size -= self.cache[key]['size']
# 腾出空间
while self.current_size + obj_size > self.max_size and self.cache:
_, oldest = self.cache.popitem(last=False)
self.current_size -= oldest['size']
# 存储新对象
expires = time.time() + ttl if ttl else None
self.cache[key] = {
'value': value,
'size': obj_size,
'expires': expires
}
self.current_size += obj_size
return True
def get(self, key):
"""获取缓存"""
if key not in self.cache:
return None
item = self.cache[key]
# 检查TTL
if item['expires'] and time.time() > item['expires']:
self.current_size -= item['size']
del self.cache[key]
return None
# 移动到最后(LRU)
self.cache.move_to_end(key)
return item['value']
def clear(self):
"""清空缓存"""
self.cache.clear()
self.current_size = 0
# 使用示例
cache = SmartMemoryCache(max_size_bytes=100*1024*1024) # 100MB
cache.set("data1", {'large': 'x' * 1000000}) # ~1MB数据
cache.set("data2", "hello", ttl=60) # 60秒后过期
result = cache.get("data1")
print(f"当前缓存大小: {cache.current_size / 1024 / 1024:.2f} MB")
使用第三方库 cacheout
# 安装: pip install cacheout
from cacheout import Cache
# 创建缓存,限制条目数
cache = Cache(maxsize=100)
# 或者使用LRU策略
from cacheout import LRUCache
lru_cache = LRUCache(maxsize=100, ttl=300) # 最多100条,TTL5分钟
# 使用
lru_cache.set('key', 'value')
print(lru_cache.get('key'))
选择建议
- 简单场景:
functools.lru_cache足够 - 需要精确内存控制:自定义
SmartMemoryCache - 需要持久化存储:
diskcache - 生产环境:
cachetools或cacheout库
根据你的具体需求选择合适的方案,如果需要更精确的内存控制,可能需要结合 psutil 等库监控实际内存使用情况。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播