你被设置的原因是试图阻止你在脚上射击自己。您的第二个类具有数据类装饰器(这是默认值)。从文档:__hash__
None
dataclasses
eq=True
以下是管理方法隐式创建的规则__hash__()
。请注意,您不能__hash__()
在数据类中同时使用显式方法并设置 unsafe_hash=True; 这将导致一个TypeError
.
如果 eq 和 freeze 都为真,默认情况下 dataclass() 将为
__hash__()
您生成一个方法。如果 eq 为真,frozen 为假,__hash__() 将被设置为 None,将其标记为不可散列(它是,因为它是可变的)。如果 eq 为假,__hash__()
将保持不变,这意味着__hash__()
将使用超类的方法(如果超类是object
,这意味着它将回退到基于 id 的散列)。
所以只需通过eq=False
:
In [1]: from dataclasses import dataclass
...:
...:
...: @dataclass
...: class Hashable:
...:
...: def __hash__(self):
...: hashed = hash((
...: getattr(self, key)
...: for key in self.__annotations__
...: ))
...: return hashed
...:
...:
...: @dataclass(eq=False)
...: class Node(Hashable):
...: name: str = 'Undefined'
...:
In [2]: hash(Node())
Out[2]: -9223372036579626267
但是,正如评论中指出的那样,这不是很安全,因为您有一个可变对象现在是可散列的,并且与它的实现不一致__eq__
,它继承自Hashable