定义`__eq__`的types是不可以的?

将function移植到我的程序的Python 3.1分支时,出现了一个奇怪的错误。 我缩小到以下假设:

与Python 2.x相反,在Python 3.x中,如果一个对象具有.__eq__方法,则它自动不可用。

这是真的?

以下是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 ,它指向了几个对象,在过去的某个时间点给出了它们的pickle dump的值。 每当一个已经存在的对象被检入时,变更跟踪器就会说新的pickle是否与旧的pickle是一样的,因此说明对象是否已经改变了。 问题是,现在我甚至不能检查给定的对象是否在库中,因为它会引发一个关于不可对象的exception。 (因为它有一个__eq__方法。)我该如何解决这个问题?

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

解决方法很简单:只需定义__hash__以及定义__eq__

本段来自http://docs.python.org/3.1/reference/datamodel.html#object。; 哈希

如果覆盖__eq__()需要保留父类的__hash__()的实现,则必须通过设置__hash__ = <ParentClass>.__hash__明确告诉解释器。 否则, __hash__()的inheritance将被阻塞,就像__hash__被显式设置为None一样。

检查object.__hash__的Python 3手册object.__hash__

如果一个类没有定义__eq__()方法,它不应该定义一个__hash__()操作。 如果它定义__eq__()而不是__hash__() ,则它的实例将不可用作可哈希集合中的项目。

重点是我的。

如果你想懒惰,听起来就像你可以定义__hash__(self)来返回id(self)

用户定义的类默认具有__eq__()__hash__()方法; 与他们,所有的对象比较不平等(除了自己)和x.__hash__()返回id(x)

我不是Python专家,但是当你定义一个eq-method的时候,你也必须定义一个hash-method(它计算一个对象的hash值),这样做没有意义。否则,哈希机制不知道它是否碰到了同一个对象,或者是一个具有相同散列值的不同对象。 实际上,这是相反的,它最终可能__eq__算出不同的散列值,这些散列值被你的__eq__方法认为是相等的。

我不知道是什么哈希函数被称为虽然, __hash__也许? 🙂