lru_cache 用于依赖于类属性的类方法 (Python)

问题描述 投票:0回答:1

我有一个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)
    将是调用项目类似功能的正确方法。

python class-method python-lru-cache
1个回答
0
投票

一种方法是分解出您想要缓存的实际函数。 您的目标是传统函数,即“这些输入始终给出此输出”:

@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)
© www.soinside.com 2019 - 2024. All rights reserved.