I have a Python classmethod Test.test(x) that produces expensive data, i.e. I would like to use functools.lru_cache as a wrapper. However, the output depends on a class attribute Test.a that can take a small number of different values. I would like to keep a cached version for each combination (a,x) of the attribute a and parameter x. I.e. I want the cache to work the usual way, as long as the attribute a is unchanged, but the method should be reevaluated once there is a change of the class attribute. How is this best achieved?
Here the code example:
from functools import lru_cache
class Test():
a = 1
def __new__(cls, a = 1):
cls.a = a
return super().__new__(cls)
@classmethod
@lru_cache(maxsize=32)
def test(cls, x):
return x * cls.a
print(Test.test(1),Test(2).test(1),Test.test(1))
Desired output (with lru_cache disabled): 1 2 2
Output with lru_cache: 1 1 1
Some clarifications:
The attribute a only gets changed rarely, hence it doesn't really matter whether there is a cached copy for each combination (a,x), or whether the cache is reset whenever the value of a changes.
The test method must be implemented that way as a classmethod (since it inherits from an abstract class which I cannot change).
Other ways to pass the value of a to the method are at least undesired.
Test(a).test(x)would be the correct way in which similar functions of the project are called.