如何使未冻结的数据类实例可散列?
How to make an unfrozen dataclass instance hashable?
当使用 frozen=False
(默认行为)定义数据class,然后实例化此 class 的对象时,有没有办法使此对象可散列?
我为什么需要这个?
在 Python 3.7 之前,我使用命名元组而不是数据 classes 并且我曾经使用 set()
查找重复项,但我不能再使用它了。
由于其他原因,我不想在数据 class 上使用 frozen=True
。
有一个参数:
@dataclass(unsafe_hash=True)
class Whatever:
...
不过,您或许应该使用 frozen=True
。如果需要更新冻结数据类实例的属性,可以使用dataclasses.replace
构造一个新对象:
new_thing = dataclasses.replace(old_thing, var=new_val)
您还可以使用可变数据类实例和 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
当使用 frozen=False
(默认行为)定义数据class,然后实例化此 class 的对象时,有没有办法使此对象可散列?
我为什么需要这个?
在 Python 3.7 之前,我使用命名元组而不是数据 classes 并且我曾经使用 set()
查找重复项,但我不能再使用它了。
由于其他原因,我不想在数据 class 上使用 frozen=True
。
有一个参数:
@dataclass(unsafe_hash=True)
class Whatever:
...
不过,您或许应该使用 frozen=True
。如果需要更新冻结数据类实例的属性,可以使用dataclasses.replace
构造一个新对象:
new_thing = dataclasses.replace(old_thing, var=new_val)
您还可以使用可变数据类实例和 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