Python очистка lru_cache каждые определенное время - PullRequest
0 голосов
/ 11 июля 2020

Я делаю много избыточных вызовов api, поэтому решил использовать lru_cache. Однако я также хотел время от времени очищать кеш на случай, если значение ответа изменится для данного ввода. Поэтому в качестве решения я создал свой собственный декоратор, чтобы очищать кеш каждый заданный промежуток времени, но теперь моя функция api_call (), кажется, всегда возвращает None, несмотря ни на что. Вот мой код:

def cache_maintainer(clear_time: int):
    """
    A function decorator that clears lru_cache clear_time seconds
    :param clear_time: In seconds, how often to clear cache (only checks when called)
    """
    def inner(func):
        def wrapper(*args, **kwargs):
            if hasattr(func, 'next_clear'):
                if time.time() > func.next_clear:
                    func.cache_clear()
                    func.next_clear = time.time() + clear_time
            else:
                func.next_clear = time.time() + clear_time

            func(*args, **kwargs)
        return wrapper
    return inner


@cache_maintainer(86400)  # clear cache every 1 day
@lru_cache(maxsize=1000)
def api_call(param):
    return param

print(api_call("test"))

Я всю жизнь не могу понять, что я сделал не так

Ответы [ 2 ]

1 голос
/ 11 июля 2020

Очень простая ошибка, на то, чтобы понять ее, потребовалось слишком много времени. Как упоминал Тим Петерс, вызывается func(), но результат отбрасывается (лицевая ладонь). Все, что мне нужно было сделать, это добавить return, в котором вызывается func(), и он работает, как я ожидал. Вот модифицированный правильно работающий код:

def cache_maintainer(clear_time: int):
    """
    A function decorator that clears lru_cache clear_time seconds
    :param clear_time: In seconds, how often to clear cache (only checks when called)
    """
    def inner(func):
        def wrapper(*args, **kwargs):
            if hasattr(func, 'next_clear'):
                if time.time() > func.next_clear:
                    func.cache_clear()
                    func.next_clear = time.time() + clear_time
            else:
                func.next_clear = time.time() + clear_time

            return func(*args, **kwargs)
        return wrapper
    return inner


@cache_maintainer(86400)  # clear cache every 1 day
@lru_cache(maxsize=1000)
def api_call(param):
    return param

print(api_call("test"))
0 голосов
/ 11 июля 2020

В этом ответе используется пакет python - cachetools

Для установки cachetools - pip install cachetools

from cachetools import TTLCache

cache = TTLCache(maxsize=5, ttl=100)
cache['dog'] = 'dog'
a = cache['dog'] # dog
... after 100 seconds...
cache['dog']
KeyError exception thrown
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...