Search code examples
pythoncachingfunctools

functools.cache - notify that the result is cached


import functools

@functools.cache
def get_some_results():
    return results

Is there a way to notify the user of the function that the results they are getting are a cached version of the original for any other time they are calling the function?


Solution

  • This isn't a perfect approach, but you could use a custom decorator instead of @functools.cache which would then wrap your function with functools.cache and gather the cache stats before and after the call to determine if the lookup resulted in a cache hit.

    This was hastily thrown together but seems to work:

    def cache_notify(func):
        func = functools.cache(func)
        def notify_wrapper(*args, **kwargs):
            stats = func.cache_info()
            hits = stats.hits
            results = func(*args, **kwargs)
            stats = func.cache_info()
            if stats.hits > hits:
                print(f"NOTE: {func.__name__}() results were cached")
            return results
        return notify_wrapper
    

    As an example of a simple function:

    @cache_notify
    def f(x):
        return -x
    
    print("calling f")
    print(f"f(1) returned {f(1)}")
    print("calling f again")
    print(f"f(1) returned {f(1)}")
    

    Results:

    calling f
    f(1) returned -1
    calling f again
    NOTE: f() results were cached
    f(1) returned -1
    

    How to "notify the user" can be tailored as needed.

    Also note that it's possible for the cache stats to be a bit misleading in a multi-threaded environment; see Python lru_cache: how can currsize < misses < maxsize? for details.