pythonpython-lru-cache

Python get the cache dictionary of _lru_cache_wrapper object


I have this simple cache decorator demo here

@functools.cache
def cached_fib(n):
    assert n > 0
    if n <= 2:
        return 1
    return cached_fib(n - 1) + cached_fib(n - 2)

t1 = time.perf_counter()
cached_fib(400)
t2 = time.perf_counter()
print(f"cached_fib: {t2 - t1}")    # 0.0004117000003134308

I want to access the actual cache dictionary object inside this cached_fib, but when I try to access through cached_fib.cache, it gives me an error saying that AttributeError: 'functools._lru_cache_wrapper' object has no attribute 'cache' though the cache attribute is used in python and c version alike.

Thank you!


Solution

  • The internals of the cache are encapsulated for thread safety and to allow the underlying implementation details to change.

    The three public attributes are, some statistics in cache_info:

    >>> cached_fib.cache_info()
    CacheInfo(hits=0, misses=0, maxsize=None, currsize=0)
    >>> cached_fib(123)
    22698374052006863956975682
    >>> cached_fib.cache_info()
    CacheInfo(hits=120, misses=123, maxsize=None, currsize=123)
    

    Details about the init mode in cache_parameters

    >>> cached_fib.cache_parameters()
    {'maxsize': None, 'typed': False}
    

    And cache_clear which purges the cache.

    >>> cached_fib.cache_info()
    CacheInfo(hits=120, misses=123, maxsize=None, currsize=123)
    >>> cached_fib.cache_clear()
    >>> cached_fib.cache_info()
    CacheInfo(hits=0, misses=0, maxsize=None, currsize=0)
    

    Additionally, the "uncached" function version is publicly available via __wrapped__, but this is not something specific to functools.cache:

    >>> cached_fib
    <functools._lru_cache_wrapper object at 0x10b7a3270>
    >>> cached_fib.__wrapped__
    <function cached_fib at 0x10bb781f0>
    

    If you want a cache implementation where the underlying dict is exposed to the user, I recommend the third-party cachetools library.