如何清理(重置)自定义缓存装饰器的缓存内存?
解决装饰器缓存重置问题
你的问题核心在于cache_reset方法没有实际执行缓存清空操作,只是返回了缓存对象。另外,给包装后的函数添加方法时,用lambda处理这类操作不够直观,我们可以用普通函数来实现。下面是修复后的完整代码:
from random import random def cached(func): cache = func.cache = {} func.call_num = 0 func.eval_num = 0 def memorised_func(*args, **kwargs): # 优化:按键排序kwargs,确保参数顺序不影响key生成(更合理的做法) key = str(args) + str(sorted(kwargs.items())) if key not in cache: cache[key] = func(*args, **kwargs) func.eval_num += 1 func.call_num += 1 print(func.call_num, func.eval_num) return cache[key] def cache_reset(): # 清空缓存,保留调用和统计次数(根据你的示例需求) func.cache.clear() # 如果需要重置统计次数,可以添加下面两行: # func.call_num = 0 # func.eval_num = 0 def cache_status(): status = f"Function {func.__name__} called {func.call_num} times, evaluated {func.eval_num} times" print(status) return status memorised_func.cache_reset = cache_reset memorised_func.cache_status = cache_status return memorised_func @cached def foo(x, y=1, z=4): return random() # 测试示例 print(foo(3) == foo(3)) print(foo(4) == foo(4)) print(foo(3, z=-1, y=3) == foo(3, y=3, z=-1)) print(foo(3) != foo(x=3)) a = foo(3) foo.cache_reset() # 现在缓存已清空 print(a != foo(3)) # 验证状态统计是否符合预期 print(foo.cache_status() == 'Function foo called 10 times, evaluated 5 times')
关键修改说明:
修复
cache_reset方法:
用普通函数cache_reset替代lambda,调用func.cache.clear()直接清空缓存。如果你的需求是连统计次数一起重置,可以取消注释函数内的两行赋值语句。优化key生成逻辑:
原来的key生成是按kwargs的值排序,改成默认的按键排序(sorted(kwargs.items())),这样能确保只要参数的键值对相同,不管传入顺序如何,都会生成相同的key,这更符合缓存的预期逻辑。重构
cache_status方法:
将原来的lambda改成普通函数,让它返回状态字符串,这样你的最后一行验证代码print(foo.cache_status() == ...)才能正常工作(原来的lambda只打印不返回,所以会和字符串比较None == ...,结果为False)。
运行修改后的代码,你会发现:
- 调用
foo.cache_reset()后,foo(3)会重新生成随机值,所以a != foo(3)的结果为True - 最后的状态统计会符合你预期的
Function foo called 10 times, evaluated 5 times,验证结果为True
内容的提问来源于stack exchange,提问作者Janek Podwysocki
相关产品推荐
相关产品推荐

