Reputation: 278
What's the best way to cache a function in python with an optional caching parameter?
I've a function which performs a database request and does not take any arguments.
Most of the times it's okay if the function uses the cached result but sometimes I want to send a new database request.
from functools import lru_cache
@lru_cache
def my_database_request_function(use_cache: bool = False):
if use_cache:
# takes response from cache
else:
# makes database request
return response
The implementation above won't work because the second time the functions gets called with the use_cache=False parameter it will not make a new request.
Upvotes: 6
Views: 1864
Reputation: 51683
Use lru_cache's cache_clear()
to clear the cached value and force a new retrieval:
[...] The decorator also provides a
cache_clear()
function for clearing or invalidating the cache. [...]
Demo:
from functools import lru_cache
what = 1 # global value for demo purposes
@lru_cache
def my_database_request_function():
return what
print(my_database_request_function())
what = 42 # change value
print(my_database_request_function()) # gets cached value
my_database_request_function.cache_clear() # clear cache
print(my_database_request_function()) # not cached
Output:
1
1 # after changing the global 'what' variable, still gets cached result
42 # after .cache_clear()
Upvotes: 4
Reputation: 71574
Here's a straightforward approach with helper functions:
from functools import lru_cache
def my_database_request_function(use_cache: bool = False):
if use_cache:
return _my_database_request_function_cached()
else:
return _my_database_request_function_fresh()
@lru_cache
def _my_database_request_function_cached():
return _my_database_request_function_fresh()
def _my_database_request_function_fresh():
# do actual database request
Upvotes: 2
Reputation: 362
from multipledispatch import dispatch
from functools import lru_cache
@dispatch(bool)
@lru_cache
def my_database_request_function(use_cache: bool):
print('cached')
@dispatch()
def my_database_request_function():
print('NOT cached')
my_database_request_function(True)
my_database_request_function(False)
my_database_request_function()
Output:
cached
cached
NOT cached
Using a module called multipledispatch, you can do function overloading where there are multiple functions of the same name and you specify the different parameters for each one. The bool here can change to anything you prefer.
Upvotes: 1