python - 如何判断对象/实例是否可哈希

标签 python hash

我最近发现了一个有趣的观察,即有些东西会影响类的对象/实例的可哈希性。我想知道如何以及为什么?

例如,我有一个名为 ListNode 的链表类:

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

   def __repr__(self):
        if self.next:
            return "{}->{}".format(self.val, repr(self.next))
        else:
            return "{}".format(self.val)

    # def __eq__(self, other):
        # if not self and not other:
        #     return True
        # elif not self or not other:
        #     return False
        # else:
        #     return self.val == other.val and self.next == other.next

     # def __eq__(self, other):
        # return str(self) == str(other)

请注意,我阻止了 __eq__ 方法。 现在,如果我创建一个实例:

A = ListNode(1)
B = ListNode(2)
C = ListNode(3)
A.next = B
B.next = C
print(hash(A))

然后它是可散列的,但是,每次运行它时我都会得到不同的输出数字。

现在,如果我取消阻止 __eq__ 方法,突然之间它就不再是可哈希的了。为什么?

看来hash方法将使用__eq__。启用 __eq__ 后它如何知道它不可哈希?

附加: 如果我编写 __eq__ 方法来比较两个链表的 str 版本(第二个 __eq__ 方法),我认为这可以解决问题,因为通过将链表转换为字符串,它变成了可哈希数据,但我仍然收到unhashable错误消息

谢谢!

According to @juanpa.arrivillaga's comment:

__eq__ 将删除默认的 __hash__ 方法,使其不可散列。 所以我添加了我自己的__hash__方法:

def __hash__(self):
    return hash(id(self))

这解决了问题,并在启用 __eq__ 的情况下使 ListNode 再次可哈希。

最佳答案

If a class does not define an __eq__() method it should not define a __hash__() operation either; if it defines __eq__() but not __hash__(), its instances will not be usable as items in hashable collections.

(...)

A class that overrides __eq__() and does not define __hash__() will have its __hash__() implicitly set to None. When the __hash__() method of a class is None, instances of the class will raise an appropriate TypeError when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when checking isinstance(obj, collections.abc.Hashable). 1

引入 __eq__() 方法因此将 __hash__() 设置为 None。您可以添加自定义哈希,以允许上面的构造:

def __hash__(self):
    return self.val

您可以在这里找到更多信息:https://docs.python.org/3/reference/datamodel.html#object.hash

关于python - 如何判断对象/实例是否可哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56298727/

相关文章:

python - python中的单元测试元类和内部类

python - 如何使用 python 以编程方式测量 HTML 源代码中元素的大小?

python - 计算日期之前的值,迭代每一行

python - 如何将参数传递给 agg pyspark 函数的字典输入

php - Google map API - 标记、MySQL

objective-c - 如何在 iOS 中计算 SHA-2(最好是 SHA 256 或 SHA 512)哈希?

c - 从文件中读取换行符分隔的项目

javascript - 带有散列密码的 php 代码无法工作

algorithm - 特殊字典的最优数据结构

python - 对 Python 中方法的内容进行哈希处理