我有一个Python类方法
Test.test(x)
,它会产生昂贵的数据,即我想使用functools.lru_cache作为包装器。但是,输出取决于类属性 Test.a
,它可以采用少量不同的值。我想为属性 a 和参数 x 的每个组合 (a,x) 保留一个缓存版本。 IE。我希望缓存以通常的方式工作,只要属性 a 不变,但是一旦类属性发生变化,就应该重新评估该方法。如何最好地实现这一目标?
这里是代码示例:
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))
所需输出(禁用 lru_cache):
1 2 2
lru_cache 输出:
1 1 1
一些澄清:
属性 a 很少更改,因此每个组合 (a,x) 是否有缓存副本,或者每当 a 的值更改时是否重置缓存并不重要。
测试方法必须以类方法的方式实现(因为它继承自一个我无法更改的抽象类)。
将 a 的值传递给方法的其他方式至少是不需要的。
Test(a).test(x)
将是调用项目类似功能的正确方法。
一种方法是分解出您想要缓存的实际函数。 您的目标是传统函数,即“这些输入始终给出此输出”:
@lru_cache(maxsize=32)
def expensive(a, x):
return x * a
class Test():
a = 1
def __new__(cls, a = 1):
cls.a = a
return super().__new__(cls)
@classmethod
def test(cls, x):
return expensive(cls.a, x)