Как обернуть functools.cache в другой декоратор?

#python

Вопрос:

Я пытаюсь сделать оболочку для functools.cache того, чтобы она срабатывала только в том случае, если self.use_cache это правда.

У меня много проблем с правильным синтаксисом в этом вопросе. Каждый раз, когда я обертываю lru_cache или cache он обрабатывает обернутую функцию как уникальный экземпляр функции и не кэширует ее. Может ли кто-нибудь помочь мне в этом?

 import functools

def cache():
    return functools.cache if self.use_cache else lambda x: x

@dataclass
class F5Query():
    use_cache: bool = True

    __hash__(self): 
        return hash(self.use_cache)

    @cache
    def _test_cache(self, input):
        """Return the same number each time if cache is working."""
        from uuid import uuid4
        return uuid4()
 

Ответ №1:

Вы можете попробовать что-то вроде этого:

 import uuid
import functools
import dataclasses

def cache(func):
    def inner(self, *args, **kwargs):
        new_func = functools.cache(func) if self.use_cache else func
        return new_func(self, *args, **kwargs)
        
    return inner

@dataclasses.dataclass
class F5Query():
    use_cache: bool = True

    @cache
    def test_cache(self):
        return uuid.uuid4()
        
query = F5Query(use_cache=True)
first = query.test_cache()
assert query.test_cache() == first

query = F5Query(use_cache=False)
first = query.test_cache()
assert query.test_cache() != first
 

Комментарии:

1. Как написано, этот код генерирует TypeError: unhashable type: 'F5Query' . Я добавил следующее: def __hash__(self): return hash(self.use_cache) . После этого он все равно возвращается: AssertionError: assert query.test_cache() == first . С другой стороны, похоже, что таким образом можно получить атрибут класса, так что спасибо вам за помощь до сих пор!