Python 文档 提到,如果您重载 __eq__
并且对象是不可变的,则应该同时重载 __hash__
,以使类能够正确地进行哈希。
在实践中,当我这样做时,我经常会得到像下面这样的代码:
class MyClass(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __eq__(self, other):
if type(other) is type(self):
return (self.a == other.a) and (self.b == other.b)
else:
return False
def __hash__(self):
return hash((self.a, self.b))
这段内容有些重复,而且很容易忘记在更新一个时更新另一个。
是否有推荐的方法来同时实现这些方法?
self.a
或self.b
的改变会导致哈希值发生变化(这将破坏各种操作)。 - rayluone = MyClass(1, 1); stuff = {one}; print(one in stuff); print(MyClass(2, 2) in stuff); one.a = one.b = 2; print(MyClass(2, 2) in stuff); print(MyClass(2, 2) in list(stuff))
this printsTrue
,False
,False
,True
. (2, 2) is "not" in the setstuff
but it's inlist(stuff)
, which doesn't use__hash__
- rayluvars(self)
或self.__dict__
代替手动定义self.__members
。但请注意,它们都返回可变且不可哈希的字典。要使用具有__hash__
的字典,请查看此答案的末尾:hash(tuple(sorted(self.__dict__.items())))
。 - Matt Popovich