定义`__eq__`类型unhashable?(Types that define `__eq__`

2019-08-31 11:43发布

移植一个功能,我的程序的Python 3.1中,叉,当我有一个奇怪的错误。 我把范围缩小到以下假设:

相反到Python 2.x中,在Python 3.X如果对象具有__eq__方法是自动unhashable。

这是真的?

下面是在Python 3.1会发生什么:

>>> 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指向几个对象,在过去的某个时间点给出了每个他们的泡菜转储的价值。 当现有的对象被选中的,变更跟踪表示,其新的泡菜是否等同于它的旧人,所以说,在此期间对象是否已经改变。 问题是,现在我甚至不能检查,如果给定对象是在图书馆,因为它使得提高对对象是unhashable例外。 (因为它有一个__eq__方法。)我如何解决此问题?

Answer 1:

是的,如果你定义__eq__ ,默认__hash__ (即,散列对象在内存中的地址)消失。 这是重要的,因为哈希需要与平等一致的:等于对象需要哈希相同。

解决方法很简单:只要定义__hash__与限定沿着__eq__



Answer 2:

这一段从http://docs.python.org/3.1/reference/datamodel.html#object。 哈希

如果覆盖了一个类__eq__()需要保留的实施__hash__()从父类,解释器必须明确通过设置被告知此__hash__ = <ParentClass>.__hash__ 。 否则的继承__hash__()将被阻塞,就像__hash__已明确设置为无。



Answer 3:

Check the Python 3 manual on object.__hash__:

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.

Emphasis is mine.

If you want to be lazy, it sounds like you can just define __hash__(self) to return id(self):

User-defined classes have __eq__() and __hash__() methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__() returns id(x).



Answer 4:

我不是专家的Python,但不会是有意义的是,当你定义EQ-方法,你也必须定义一个散列法以及(其计算对象的哈希值),否则,散列机制不知道,如果它击中同一个对象,或只用相同的哈希值不同的对象。 其实,这是周围的其他方法,它很可能为这样的考虑你相等的对象不同的计算哈希值__eq__方法。

我不知道那是什么散列函数,虽然叫, __hash__吧? :)



文章来源: Types that define `__eq__` are unhashable?