如何使用 Python 装饰器以便方法使用 functools.lru_cache 并自行注册?
Posted
技术标签:
【中文标题】如何使用 Python 装饰器以便方法使用 functools.lru_cache 并自行注册?【英文标题】:How to use Python decorators so that a method uses functools.lru_cache andregisters itself? 【发布时间】:2020-10-10 00:53:07 【问题描述】:我正在使用 lru_cache 访问数据存储的类中装饰一些方法。我想应用另一个装饰器,或者以另一种方式调用 lru_cache,以便在第一次调用时将缓存方法添加到集合中。这样,当我知道我的数据存储是脏的时,我可以清理每个方法的缓存。换句话说,我如何在下面构建“register_data_reader”?还是我应该换一种方式?
from functools import lru_cache
class foo:
_cached_funcs = set()
@register_data_reader # adds the LRU DECORATED func to _cached_funcs
@lru_cache(maxsize=16)
def reads_data_somewhere(self, ...)
...
return data
def clear_cache(self):
for f in _cached_funcs:
f.cache_clear()
【问题讨论】:
【参考方案1】:只是想知道如何实现它...为什么还要费心用装饰器注册方法并在_cache_funcs
中跟踪它们?而是遍历类方法并尝试在它们上运行.cache_clear()
?
class Foo:
@lru_cache(maxsize=16)
def reads_data_somewhere(self):
return 2 + 2
def clear_cache(self):
for method in dir(self):
try:
getattr(self, method).cache_clear()
except AttributeError:
pass
f = Foo()
print(f.reads_data_somewhere())
print(f.reads_data_somewhere())
print(f.reads_data_somewhere())
print(f.reads_data_somewhere())
print(f.reads_data_somewhere.cache_info())
f.clear_cache()
print(f.reads_data_somewhere.cache_info())
输出:
4
4
4
4
CacheInfo(hits=3, misses=1, maxsize=16, currsize=1)
CacheInfo(hits=0, misses=0, maxsize=16, currsize=0)
【讨论】:
【参考方案2】:谢谢特里,这很有用。
最后,受您的启发,我在班级的 init 中运行以下方法。它允许我绕过抛出异常,并且我正在注册一次缓存的方法,因为与总数相比相对较少。
Class foo:
...
def _register_cache(self):
lst = dir(self)
for method in lst:
if hasattr(getattr(self, method), "cache_info"):
self._cached_methods.add(method)
【讨论】:
以上是关于如何使用 Python 装饰器以便方法使用 functools.lru_cache 并自行注册?的主要内容,如果未能解决你的问题,请参考以下文章