cara/caimira/utils.py
2022-09-09 16:57:20 +02:00

27 lines
835 B
Python

import functools
def method_cache(fn):
"""
A decorator for instance based caching.
Unlike lru_cache / memoization, this allows us to not have to have the
instance itself be hashable - only the arguments must be so.
The cache is stored as a dictionary in a private attribute on the instance
with the name ``_cache_{func_name}``.
"""
cache_name = f'_cache_{fn.__name__}'
@functools.wraps(fn)
def cached_method(self, *args, **kwargs):
cache = getattr(self, cache_name, None)
if cache is None:
cache = {}
object.__setattr__(self, cache_name, cache)
cache_key = hash(args + tuple(kwargs.items()))
if cache_key not in cache:
cache[cache_key] = fn(self, *args, **kwargs)
return cache[cache_key]
return cached_method