在Python3中,任何类都将具有默认的__hash__
,该默认值将根据成员变量来计算哈希值。我可以将其(显式或隐式)设置为None,以使该类不可哈希,这肯定有一些用例。
但是有理由要覆盖__hash__
吗?
我找不到一个。
答案 0 :(得分:2)
是的!任何时候您覆盖__eq__
,并且还希望能够将对象用作集合或字典中的键时。这在值类型或对象代表现实世界实体的情况下尤其常见。
__hash__
完全不散列成员变量。对于未定义__hash__
或__eq__
的对象,它将根据其内部指针返回一些值。如果定义了__eq__
,则调用该方法将导致TypeError.work
考虑以下简单情况,其中默认的__eq__
和__hash__
行为并不理想:
import getpass
class User:
def __init__(self, name):
self.name = name
def currentUser():
return User(getpass.getuser())
me = currentUser()
passwords = {}
passwords[me] = "sw0rdfish";
这有一些奇怪的行为:me == currentUser()
为假,而passwords[currentUser()]
抛出KeyError。因此,为了解决此问题,我们定义了一个__eq__
:
def __eq__(self, other):
return self.name == other.name
现在me == currentUser()
是正确的,但是尝试分配密码会抛出TypeError: unhashable type: 'User'
。现在我们到了要覆盖__hash__
的地步:
def __hash__(self):
return hash(self.name)
现在,它的行为就像您期望其他任何此类对象用作键时一样。