为什么 `int.__eq__(other)` 是一个有效的比较?

abu*_*kaj 1 python python-2.7

以下代码适用于 Python 2.7:

>>> class Derived(int):
...     def __eq__(self, other):
...         return int.__eq__(other)
...
>>> Derived(12) == 12.0
True
>>> Derived(12) == 13
False
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它会起作用,因为该self属性没有显式地提供给int.__eq__()方法调用。

[编辑]

到目前为止的答案表明,这是关于返回NotImplementedself.__eq__(other)因此调用other.__eq__(self)。然后Derived(12) == Derived(12)我期望是一个不定式递归,但事实并非如此:

>>> Derived(12) == Derived(12)
True
Run Code Online (Sandbox Code Playgroud)

Ash*_*ary 5

它之所以有效,是因为int.__eq__(<something>)返回NotImplemented,当发生返回时,它会导致调用andother.__eq__(self)这就是返回的内容。TrueFalse

\n\n

演示:

\n\n
class Derived(int):\n     def __eq__(self, other):\n         print self, other\n         print int.__eq__(other)\n         print other.__eq__(self)\n         return int.__eq__(other)\n\n>>> Derived(12) == 12.0\n12 12.0\nNotImplemented\nTrue\nTrue\n>>> Derived(12) == 13.0\n12 13.0\nNotImplemented\nFalse\nFalse\n
Run Code Online (Sandbox Code Playgroud)\n\n

来自NotImplemented\n\的文档:

\n\n
\n

二进制特殊方法(例如 、 、 、 等)应返回的特殊值__eq__()表明__lt__()__add__()操作__rsub__()未针对其他类型实现;出于相同目的,可以通过就地二进制特殊方法\n(例如 、 等)返回__imul__()__iand__()它的真值是 true。

\n\n

注意 当NotImplemented返回时,解释器将尝试\n 其他类型上的反射操作,或其他一些回退,\n 取决于运算符。如果所有尝试的操作都返回 NotImplemented,则解释器将引发适当的异常。

\n
\n\n
\n\n

__eq__当两人都回来时会发生什么NotImplemented

\n\n

Python 2 和 3 中的行为有所不同。

\n\n

在 Python 2 中,它退回到__cmp__方法优先,并且整数__cmp__在 Python 2 中具有方法。它已在 Python 3 中删除。

\n\n

根据 Python 2 文档,如果没有找到任何内容,它最终会退回到身份比较:

\n\n
\n

如果未定义__cmp__(),__eq__()__ne__()操作,则按对象标识 (\xe2\x80\x9caddress\xe2\x80\x9d) 比较类\n 实例

\n
\n\n
class Derived(int):\n    def __eq__(self, other):\n        print ("Inside  __eq__")\n        return NotImplemented\n\n    def __cmp__(self, other):\n        print ("Inside __cmp__ finally")\n        return True\n\n>>> Derived(12) == Derived(12)\nInside  __eq__\nInside  __eq__\nInside __cmp__ finally\nFalse\n
Run Code Online (Sandbox Code Playgroud)\n\n

不要定义一个没有定义方法的类:

\n\n
class Derived(object):\n    pass\n\n>>> Derived() == Derived()  \nFalse\n>>> d = Derived()\n>>> d == d  # Same objects.\nTrue\n
Run Code Online (Sandbox Code Playgroud)\n\n

Python 3 不再有__cmp__方法,但现在似乎又回到了身份。而且似乎也没有记录。

\n\n
#  Python 3.5\n>>> Derived() == Derived()\nFalse\n>>> d = Derived()\n>>> d == d\nTrue\n
Run Code Online (Sandbox Code Playgroud)\n