有覆盖__hash__的用例吗?

时间:2019-06-25 04:53:07

标签: python-3.x hash magic-function

在Python3中,任何类都将具有默认的__hash__,该默认值将根据成员变量来计算哈希值。我可以将其(显式或隐式)设置为None,以使该类不可哈希,这肯定有一些用例。

但是有理由要覆盖__hash__吗?

我找不到一个。

1 个答案:

答案 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)

现在,它的行为就像您期望其他任何此类对象用作键时一样。