代码之家  ›  专栏  ›  技术社区  ›  Ram Rachum

定义“eq”的类型是不可显示的?

  •  57
  • Ram Rachum  · 技术社区  · 15 年前

    当我将一个特性移植到我的程序的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相同,因此会说这个对象是否同时发生了变化。问题是,现在我甚至无法检查给定的对象是否在库中,因为它会引发一个关于对象不可显示的异常。(因为它有一个 爱斯克 方法。)我如何解决这个问题?

    4 回复  |  直到 6 年前
        1
  •  57
  •   Martin v. Löwis    15 年前

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

    解决方案很简单:只需定义 阿什哈什尔 以及定义 爱斯克 .

        2
  •  22
  •   newacct    15 年前

    此段落来自 http://docs.python.org/3.1/reference/datamodel.html#object. hash

    如果一个类重写 __eq__() 需要保持执行 __hash__() 在父类中,必须告诉解释器 通过设置显式 __hash__ = <ParentClass>.__hash__ . 否则 继承 α-Hasih() 将 封锁,就像 __hash__ 曾经 显式设置为无。

        3
  •  3
  •   Mark Rushakoff    15 年前

    查看python 3手册 object.__hash__ :

    如果类没有定义 __eq__() 方法不应定义 __hash__() 操作; 如果定义 α-ε() 但不是 α-Hasih() ,其实例将不能用作哈希集合中的项。

    重点是我的。

    如果你想懒惰,听起来你可以定义 __hash__(self) 归来 id(self) :

    用户定义的类具有 α-ε() α-Hasih() 方法;使用它们,所有对象都比较不相等(除了它们本身)和 x.__hash__() 收益率 id(x) .

        4
  •  1
  •   falstro    15 年前

    我不是Python专家,但在定义eq方法时,也必须定义哈希方法(它计算对象的哈希值),这是否有意义呢?否则,哈希机制将不知道它是命中同一对象,还是只命中具有相同哈希值的不同对象。实际上,它是相反的,它可能最终会为被认为是相等的对象计算不同的散列值。 __eq__ 方法。

    我不知道这个哈希函数叫什么, __hash__ 也许?:)