Search code examples
pythonpython-decoratorsfunctools

disable `functools.lru_cache` from inside function


I want to have a function that can use functools.lru_cache, but not by default. I am looking for a way to use a function parameter that can be used to disable the lru_cache. Currently, I have a two versions of the function, one with lru_cache and one without. Then I have another function that wraps these with a parameter that can be used to control which function is used

def _no_cache(foo):
    print('_no_cache')
    return 1


@lru_cache()
def _with_cache(foo):
    print('_with_cache')
    return 0


def cache(foo, use_cache=False):
    if use_cache:
        return _with_cache(foo)
    return _no_cache(foo)

Is there a simpler way to do this?


Solution

  • You can't disable the cache from inside the decorated function. However, you can simplify your code a bit by accessing the function directly via the __wrapped__ attribute.

    From the documentation:

    The original underlying function is accessible through the __wrapped__ attribute. This is useful for introspection, for bypassing the cache, or for rewrapping the function with a different cache.

    Demo:

    from functools import lru_cache
    
    @lru_cache()
    def f(arg):
        print(f"called with {arg}")
        return arg    
    
    def call(arg, use_cache=False):
        if use_cache:
            return f(arg)
        return f.__wrapped__(arg)
    
    call(1)
    call(1, True)
    call(2, True)
    call(1, True)
    

    Output:

    called with 1
    called with 1
    called with 2