Python脚本如何限制单类缓存存储数量

wen python案例 29

本文目录导读:

Python脚本如何限制单类缓存存储数量

  1. 使用 @lru_cache 装饰器(内置支持)
  2. 使用 @cache 装饰器(Python 3.9+)
  3. 自定义 LRU 缓存类
  4. 使用第三方库 cachetools
  5. 基于字典的简单限制
  6. 装饰器版本的限制缓存
  7. 选择建议

在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)
  • 注意缓存对象的生命周期管理

抱歉,评论功能暂时关闭!