1

我正在使用 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()

4

2 回答 2

2

只是关于如何实现这个的想法......为什么还要费心用装饰器注册方法并跟踪它们_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)
于 2020-06-19T19:52:45.283 回答
1

谢谢特里,这很有用。

最后,受您的启发,我在班级的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)
于 2020-06-24T12:45:51.820 回答