修改some_list时如何清空属性绑定的@lru_cache缓存
解决方案
你可以通过主动触发缓存失效的方式实现需求,以下是两种常用的可行方案:
方案1:封装some_list写入操作,修改时主动清空lru缓存
你当前写法中@property + @lru_cache的缓存实例绑定在属性的getter方法上,只需要在每次修改some_list时调用cache_clear()方法即可清空对应缓存:
from functools import lru_cache class YourClass: def __init__(self): # 将内部存储的列表改为受保护属性,避免外部直接修改 self._some_list = [] self.some_dict = {} @property @lru_cache(maxsize=None) def attribute(self): attribute = {} for k in self.some_dict: attribute[k] = self.complex_computation(self._some_list) return attribute # 对外提供some_list的只读访问(可选) @property def some_list(self): # 返回拷贝防止外部直接修改内部原始列表 return self._some_list.copy() # 封装列表赋值操作,修改后主动清空缓存 def set_some_list(self, new_list): self._some_list = new_list # property装饰后的原始方法存在fget属性中,调用其cache_clear清空缓存 self.attribute.fget.cache_clear() # 封装列表追加操作(按你的需求扩展其他修改方法即可) def append_some_list(self, item): self._some_list.append(item) self.attribute.fget.cache_clear() def complex_computation(self, lst): # 你的原有计算逻辑 pass
方案2:使用cached_property简化失效逻辑(Python 3.8+适用)
Python 3.8及以上版本的functools模块提供了专门用于实例属性缓存的cached_property装饰器,缓存直接存储在实例的__dict__中,失效逻辑更简单:
from functools import cached_property class YourClass: def __init__(self): self._some_list = [] self.some_dict = {} @cached_property def attribute(self): attribute = {} for k in self.some_dict: attribute[k] = self.complex_computation(self._some_list) return attribute def set_some_list(self, new_list): self._some_list = new_list # 直接删除实例上的attribute属性即可清空缓存,下次访问会自动重新计算 if 'attribute' in self.__dict__: del self.__dict__['attribute']
注意事项
- 不要对外暴露原始的
_some_list对象,避免外部直接修改列表内容未触发缓存失效,导致返回脏数据 - 如果你的
some_dict也会发生修改,需要在修改some_dict的逻辑里同步执行缓存清空操作
内容的提问来源于stack exchange,提问作者stn1997
相关产品推荐
相关产品推荐

