以下代码适用于 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__()方法调用。
[编辑]
到目前为止的答案表明,这是关于返回NotImplemented并self.__eq__(other)因此调用other.__eq__(self)。然后Derived(12) == Derived(12)我期望是一个不定式递归,但事实并非如此:
>>> Derived(12) == Derived(12)
True
Run Code Online (Sandbox Code Playgroud)
它之所以有效,是因为int.__eq__(<something>)返回NotImplemented,当发生返回时,它会导致调用andother.__eq__(self)这就是返回的内容。TrueFalse
演示:
\n\nclass 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\nRun Code Online (Sandbox Code Playgroud)\n\n来自NotImplemented\n\的文档:
\n\n\n二进制特殊方法(例如 、 、 、 等)应返回的特殊值
\n\n__eq__()表明__lt__()该__add__()操作__rsub__()未针对其他类型实现;出于相同目的,可以通过就地二进制特殊方法\n(例如 、 等)返回__imul__()。__iand__()它的真值是 true。注意 当
\nNotImplemented返回时,解释器将尝试\n 其他类型上的反射操作,或其他一些回退,\n 取决于运算符。如果所有尝试的操作都返回 NotImplemented,则解释器将引发适当的异常。
__eq__当两人都回来时会发生什么NotImplemented?
Python 2 和 3 中的行为有所不同。
\n\n在 Python 2 中,它退回到__cmp__方法优先,并且整数__cmp__在 Python 2 中具有方法。它已在 Python 3 中删除。
根据 Python 2 文档,如果没有找到任何内容,它最终会退回到身份比较:
\n\n\n\n\n如果未定义
\n__cmp__(),__eq__()或__ne__()操作,则按对象标识 (\xe2\x80\x9caddress\xe2\x80\x9d) 比较类\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\nRun Code Online (Sandbox Code Playgroud)\n\n不要定义一个没有定义方法的类:
\n\nclass Derived(object):\n pass\n\n>>> Derived() == Derived() \nFalse\n>>> d = Derived()\n>>> d == d # Same objects.\nTrue\nRun Code Online (Sandbox Code Playgroud)\n\nPython 3 不再有__cmp__方法,但现在似乎又回到了身份。而且似乎也没有记录。
# Python 3.5\n>>> Derived() == Derived()\nFalse\n>>> d = Derived()\n>>> d == d\nTrue\nRun Code Online (Sandbox Code Playgroud)\n