Заставить @lru_cache игнорировать некоторые аргументы функции

Как заставить декоратор @functools.lru_cache игнорировать некоторые аргументы функции с помощью что касается ключа кеширования?

Например, у меня есть функция, которая выглядит так:

def find_object(db_handle, query):
    # (omitted code)
    return result

Если я просто так применю декоратор lru_cache, то db_handle будет включен в ключ кеша. В результате, если я попытаюсь вызвать функцию с тем же query, но другим db_handle, она будет выполнена снова, чего я хотел бы избежать. Я хочу, чтобы lru_cache учитывал только query аргумент.


person WGH    schedule 09.06.2015    source источник


Ответы (2)


С помощью cachetools вы можете написать:

from cachetools import cached
from cachetools.keys import hashkey

from random import randint

@cached(cache={}, key=lambda db_handle, query: hashkey(query))
def find_object(db_handle, query):
    print("processing {0}".format(query))
    return query

queries = list(range(5))
queries.extend(range(5))
for q in queries:
    print("result: {0}".format(find_object(randint(0, 1000), q)))
person Yann    schedule 18.09.2015

У меня есть по крайней мере одно очень уродливое решение. Оберните db_handle в объект, который всегда равен, и разверните его внутри функции.

Для этого требуется декоратор с большим количеством вспомогательных функций, что делает трассировку стека довольно запутанной.

class _Equals(object):
    def __init__(self, o):
        self.obj = o

    def __eq__(self, other):
        return True

    def __hash__(self):
        return 0

def lru_cache_ignoring_first_argument(*args, **kwargs):
    lru_decorator = functools.lru_cache(*args, **kwargs)

    def decorator(f):
        @lru_decorator
        def helper(arg1, *args, **kwargs):
            arg1 = arg1.obj
            return f(arg1, *args, **kwargs)

        @functools.wraps(f)
        def function(arg1, *args, **kwargs):
            arg1 = _Equals(arg1)
            return helper(arg1, *args, **kwargs)

        return function

    return decorator
person WGH    schedule 09.06.2015