Как использовать декораторы Python, чтобы метод использовал functools.lru_cache и сам регистрировал? - PullRequest
0 голосов
/ 19 июня 2020

Я украшаю некоторые методы в классе, который обращается к хранилищу данных, с помощью 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()

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Просто подумал, как это реализовать ... Зачем вообще заморачиваться с регистрацией методов с помощью декоратора и отслеживанием их в _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)
0 голосов
/ 24 июня 2020

Спасибо, Терри, это было полезно.

В конце концов, я запускаю следующий метод в 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...