如何使未冻结的数据类实例可散列?

Dav*_* D. 4 python python-dataclasses

定义数据类时 frozen=False(默认行为),然后实例化这个类的一个对象时,有没有办法让这个对象可以散列?

为什么我需要这个?

在 Python 3.7 之前,我使用命名元组而不是数据类,我曾经使用 查找重复项set(),但我不能再使用它了。frozen=True由于其他原因,我不想在数据类上使用。

use*_*ica 5

有一个参数:

@dataclass(unsafe_hash=True)
class Whatever:
    ...
Run Code Online (Sandbox Code Playgroud)

不过,您可能应该使用frozen=True。如果您需要更新冻结数据类实例上的属性,您可以使用dataclasses.replace来构造一个新对象:

new_thing = dataclasses.replace(old_thing, var=new_val)
Run Code Online (Sandbox Code Playgroud)

您还可以使用可变数据类实例并dataclasses.astuple在需要可散列的内容时获取元组。不过要小心 -astuple有一堆奇怪的复制行为,所以你可以得到如下行为:

In [1]: import dataclasses

In [2]: @dataclasses.dataclass
   ...: class Foo:
   ...:     a: object
   ...:     b: object
   ...:     

In [3]: x = object()

In [4]: a = Foo(x, x)

In [5]: b = dataclasses.astuple(a)

In [6]: b[0] is b[1]
Out[6]: False

In [7]: b[0] is x
Out[7]: False

In [8]: a == a
Out[8]: True

In [9]: dataclasses.astuple(a) == dataclasses.astuple(a)
Out[9]: False
Run Code Online (Sandbox Code Playgroud)