Reputation: 164
How do you disable caching when working with pythons functools? We have a boolean setting where you can disable the cache. This is for working locally.
I thought something like this:
@lru_cache(disable=settings.development_mode)
But there is no setting like that. Am I missing something? How are people doing this?
Upvotes: 2
Views: 132
Reputation: 982
lru_cache exposes a few functions on the cached function.
E.g. cache_info()
, cache_clear()
, and __wrapped__()
So here's two options:
import random
@lru_cache
def foo():
return random.random()
def test_foo():
foo()
# Clear cache
foo.cache_clear()
# Call again
foo()
# Call underlying function, uncached
foo.__wrapped__()
cache_info()
might also be useful for introspection of the cache status. E.g.
> foo.cache_info()
CacheInfo(hits=1, misses=1, maxsize=128, currsize=1)
Docs: https://docs.python.org/3/library/functools.html#functools.lru_cache
Upvotes: 0
Reputation: 2294
If you want to disable caching conditionally while using functools.lru_cache,
you need to manage this manually, You need a decorator that can conditionally apply lru_cache based on your settings
I am using the docs as the guide docsOnFunctools
Quotes from docs:
If maxsize is set to None, the LRU feature is disabled and the cache can grow without bound.If typed is set to true, function arguments of different types will be cached separately. If typed is false, the implementation will usually regard them as equivalent calls and only cache a single result. (Some types such as str and int may be cached separately even when typed is false.)
from functools import lru_cache, wraps
def remove_lru_cache(maxsize=128, typed=False, enable_cache=True):
def decorator(func):
if enable_cache:
return lru_cache(maxsize=maxsize, typed=typed)(func)
return func
return decorator
Then you can apply it to your code
# settings
your_settings = {
'dev_mode': True #set False to enable caching
}
@remove_lru_cache(maxsize=None, typed=False, enable_cache=not settings['dev_mode'])
def add(nums: List[int]) -> int:
return sum(nums)
Upvotes: 2
Reputation: 107015
You can apply the decorator conditionally instead:
def f(x):
return 2 * x
if not settings.development_mode:
f = lru_cache(f)
Upvotes: 0
Reputation: 1629
You could give a maxsize of 0 (or negative for that matter), which will effectively turn off the cache since no values can enter the cache at all.
import functools
@functools.lru_cache(maxsize=0)
def f(a):
print("entered the function in f")
@functools.lru_cache
def g(a):
print("entered the function in g")
f(1)
f(1) # -> will also show "entered the function in f", thus not using the cache
g(1)
g(1) # -> does not show anything, thus using the cache
For your example this means that you could use a variable to set the size, and when you want to disable it set that variable to 0.
Upvotes: 1