How do I use cache_clear() on python @functools.lru_cache
Question:
The documentation states:
The decorator also provides a cache_clear()
function for clearing or
invalidating the cache.
It doesn’t provide any examples or guidance on how to use cache_clear()
I have two questions:
- How can I run
cache_clear()
from a different function?
- If I put a
cache_clear()
call conditionally inside the function that is being cached, will it ever get executed?
Answers:
Besides caching, lru_cache
decorator also adds new functions, to the decorated function – cache_info
and cache_clear
. Below is a simple example that should explain how they work:
>>> @lru_cache(5)
... def foo():
... print('Executing foo...')
...
>>> foo()
Executing foo...
>>> foo()
>>> foo.cache_info()
CacheInfo(hits=1, misses=1, maxsize=5, currsize=1)
>>> foo.cache_clear()
>>> foo()
Executing foo...
Answering your questions:
If I put a cache_clear() call conditionally inside the function that is being cached, will it ever get executed?
If the result is not cached already, the function will execute and based on your conditions, it should execute cache_clear
. I wouldn’t use such solution though – a good practise is to invalidate outside the cached object, otherwise you risk no invalidation at all in worst cases, unreadable code in best case.
How can I run cache_clear() from a different function?
Just import cached function and call cache_clear
on it:
from x import foo
def bar():
foo.cache_clear()
If the method you are trying to expire the cache for is a property:
class Foo:
@property
@lru_cache()
def bar(self):
return 42
Then you can clear the cache this way:
Foo.bar.fget.cache_clear()
See this answer: https://stackoverflow.com/a/55497384/8953378
If the method is decorated by custom functions, like:
Class myclass
@dec1
@dec2
...
@decX
@lru_cache()
def myfunc()
its also possible to access the lru_cache
wrapper by accessing the __dict__
and then the __wrapped__
key in it, as many times as needed, like this:
myclass.myfunc.__dict__["__wrapped__"].__dict__["__wrapped__"].....__dict__["__wrapped__"]cache_clear()
The documentation states:
The decorator also provides a
cache_clear()
function for clearing or
invalidating the cache.
It doesn’t provide any examples or guidance on how to use cache_clear()
I have two questions:
- How can I run
cache_clear()
from a different function? - If I put a
cache_clear()
call conditionally inside the function that is being cached, will it ever get executed?
Besides caching, lru_cache
decorator also adds new functions, to the decorated function – cache_info
and cache_clear
. Below is a simple example that should explain how they work:
>>> @lru_cache(5)
... def foo():
... print('Executing foo...')
...
>>> foo()
Executing foo...
>>> foo()
>>> foo.cache_info()
CacheInfo(hits=1, misses=1, maxsize=5, currsize=1)
>>> foo.cache_clear()
>>> foo()
Executing foo...
Answering your questions:
If I put a cache_clear() call conditionally inside the function that is being cached, will it ever get executed?
If the result is not cached already, the function will execute and based on your conditions, it should execute cache_clear
. I wouldn’t use such solution though – a good practise is to invalidate outside the cached object, otherwise you risk no invalidation at all in worst cases, unreadable code in best case.
How can I run cache_clear() from a different function?
Just import cached function and call cache_clear
on it:
from x import foo
def bar():
foo.cache_clear()
If the method you are trying to expire the cache for is a property:
class Foo:
@property
@lru_cache()
def bar(self):
return 42
Then you can clear the cache this way:
Foo.bar.fget.cache_clear()
See this answer: https://stackoverflow.com/a/55497384/8953378
If the method is decorated by custom functions, like:
Class myclass
@dec1
@dec2
...
@decX
@lru_cache()
def myfunc()
its also possible to access the lru_cache
wrapper by accessing the __dict__
and then the __wrapped__
key in it, as many times as needed, like this:
myclass.myfunc.__dict__["__wrapped__"].__dict__["__wrapped__"].....__dict__["__wrapped__"]cache_clear()