如何组合数据类、属性 和 lru_cache

How to combine dataclass, property, and lru_cache

我正在尝试将数据类、属性和 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'

有办法解决这个问题吗?

lru_cache 就像记忆,所以它散列传递给函数的参数并存储结果。你的 class 不可哈希。要使其可哈希,请添加类似这样的内容

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

原因是这 3 个属性使每个实例都“独一无二”——我们不需要对方法进行哈希处理,因为所有实例都具有相同的方法。

在大多数正常的 classes 上,它的 __dict__ 用于一般哈希,除非找到 __hash__ 方法。 dataclass 文档解释了 dataclass 可以生成哈希方法,但这取决于您如何设置 dataclass,因为默认情况下该对象被假定为可变的(并且像列表这样的可变对象不能被散列)。

dataclass文档指出,如果使用[=17=装饰时参数eqfrozen设置为True,将生成一个hash方法],但您的应用程序可能无法保证这一点,因为 frozen 禁止对 实例 进行属性分配。

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