j. DOE
j. DOE

Reputation: 278

python optional caching of function

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

Answers (3)

Patrick Artner
Patrick Artner

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

Samwise
Samwise

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

Tario You
Tario You

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

Related Questions