I have an object with a method/property multiplier
. This method is called many times in my program, so I've decided to use lru_cache()
on it to improve the execution speed. As expected, it is much faster:
The following code shows the problem:
from functools import lru_cache
class MyClass(object):
def __init__(self):
self.current_contract = 201706
self.futures = {201706: {'multiplier': 1000},
201712: {'multiplier': 25}}
@property
@lru_cache()
def multiplier(self):
return self.futures[self.current_contract]['multiplier']
CF = MyClass()
assert CF.multiplier == 1000
CF.current_contract = 201712
assert CF.multiplier == 25
The 2nd assert
fails, because the cached value is 1000 as lru_cache()
is unaware that the underlying attribute current_contract
was changed.
Is there a way to clear the cache when self.current_contract is updated?
Thanks!
Yes quite simply: make current_contract
a read/write property and clear the cache in the property's setter:
from functools import lru_cache
class MyClass(object):
def __init__(self):
self.futures = {201706: {'multiplier': 1000},
201712: {'multiplier': 25}}
self.current_contract = 201706
@property
def current_contract(self):
return self._current_contract
@current_contract.setter
def current_contract(self, value):
self._current_contract = value
type(self).multiplier.fget.cache_clear()
@property
@lru_cache()
def multiplier(self):
return self.futures[self.current_contract]['multiplier']
NB : I assume your real use case involves costly computations instead of a mere dict lookup - else lru_cache
might be a bit overkill ;)