首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >定义`__eq__`的类型是不可散列的吗?

定义`__eq__`的类型是不可散列的吗?
EN

Stack Overflow用户
提问于 2009-10-23 01:46:32
回答 2查看 13.6K关注 0票数 80

当我将一个特性移植到我的程序的Python3.1fork时,我遇到了一个奇怪的bug。我把它的范围缩小到以下假设:

与Python2.x不同的是,在Python3.x中,如果一个对象有一个__eq__方法,那么它就是自动不可散列的。

这是真的吗?

以下是Python 3.1中发生的事情:

代码语言:javascript
复制
>>> class O(object):
...     def __eq__(self, other):
...         return 'whatever'
...
>>> o = O()
>>> d = {o: 0}
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    d = {o: 0}
TypeError: unhashable type: 'O'

接下来的问题是,我如何解决我的个人问题?我有一个对象ChangeTracker,它存储一个指向多个对象的WeakKeyDictionary,给出每个对象在过去某个时间点的酸洗转储的值。无论何时签入现有的对象,变更跟踪器都会判断其新的pickle是否与旧的相同,因此会指出该对象在此期间是否已更改。问题是,现在我甚至不能检查给定的对象是否在库中,因为它会引发一个关于该对象不可散列的异常。(因为它有一个__eq__方法。)我该如何解决这个问题呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-10-23 01:51:11

是的,如果你定义了__eq__,默认的__hash__ (也就是散列内存中对象的地址)就消失了。这一点很重要,因为散列需要与相等一致:相等的对象需要散列相同的内容。

解决方案很简单:只需在定义__eq__的同时定义__hash__

票数 88
EN

Stack Overflow用户

发布于 2009-10-23 01:49:38

我不是python专家,但是当你定义一个eq-method时,你也必须定义一个散列方法(它计算一个对象的散列值),这不是很有意义吗?否则,散列机制将不知道它是命中相同的对象,还是使用相同的散列值的不同对象。实际上,情况正好相反,它可能会为__eq__方法认为相等的对象计算不同的散列值。

我不知道这个散列函数叫什么,也许是__hash__?:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1608842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档