如何合并数据类,属性和lru_cache

时间:2019-08-05 08:56:04

标签: python properties lru python-dataclasses

我正在尝试将数据类,属性和lru_caches结合起来以用于一些计算科学代码:

from dataclasses import dataclass
from typing import Any
from functools import lru_cache
@dataclass
class F:
    a: Any = 1
    b: Any = 2
    c: Any = 3
    @property
    @lru_cache(1)
    def d(self):
        print('Computing d')
        return (self.a+self.b)**self.c
f=F()
print(f.d)
print(f.d)

我希望看到

Computing d
27
27

但是得到

TypeError: unhashable type: 'F'

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:2)

lru_cache就像备忘录一样,因此它哈希传递给函数的参数并存储结果。您的课程不可散列。要使其可散列,请添加如下内容

class F:
    ....
    def __hash__(self):
        return hash((self.a, self.b, self.c))

之所以这样做,是因为这3个属性使每个实例“唯一”-我们无需对方法进行哈希处理,因为所有实例都具有相同的方法。

在大多数普通类中,除非找到__dict__方法,否则它将__hash__用于常规哈希。数据类文档解释说,数据类可能会生成哈希方法,但这取决于您如何设置数据类,因为默认情况下该对象被认为是可变的(并且可变对象(如列表)不能被哈希)。

数据类文档指出,如果在用eq装饰时将参数frozenTrue设置为@dataclass(),则会生成一个散列方法,但是您的应用程序可能不会frozen禁止在实例上分配属性。

https://docs.python.org/3/library/dataclasses.html#dataclasses.dataclass