Skip to main content
 首页 » 编程设计

python之为什么 `int.__eq__(other)` 是工作比较

2025年05月04日24linjiqin

以下代码适用于 Python 2.7:

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

我不明白为什么它会起作用,因为 self 属性没有明确地赋予 int.__eq__() 方法调用。

[编辑]

到目前为止的答案表明,它是关于通过 self.__eq__(other) 返回 NotImplemented 并因此调用 other.__eq__(self)。然后Derived(12) == Derived(12)我期望是不定式递归,结果不是这样的:

>>> Derived(12) == Derived(12) 
True 

请您参考如下方法:

之所以有效,是因为 int.__eq__(<something>)返回 NotImplemented当这种情况发生时,它会调用 other.__eq__(self)这就是返回的 True和 False在这里。

演示:

class Derived(int): 
     def __eq__(self, other): 
         print self, other 
         print int.__eq__(other) 
         print other.__eq__(self) 
         return int.__eq__(other) 
 
>>> Derived(12) == 12.0 
12 12.0 
NotImplemented 
True 
True 
>>> Derived(12) == 13.0 
12 13.0 
NotImplemented 
False 
False 

来自 NotImplemented 的文档:

Special value which should be returned by the binary special methods (e.g. __eq__(), __lt__(), __add__(), __rsub__(), etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. __imul__(), __iand__(), etc.) for the same purpose. Its truth value is true.

Note When NotImplemented is returned, the interpreter will then try the reflected operation on the other type, or some other fallback, depending on the operator. If all attempted operations return NotImplemented, the interpreter will raise an appropriate exception.


当 __eq__ 都发生时会发生什么?返回 NotImplemented ?

Python 2 和 3 中的行为不同。

在 Python 2 中它回落到 __cmp__方法优先,整数有 __cmp__ method in Python 2 .它已在 Python 3 中被删除。

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

If no __cmp__(), __eq__() or __ne__() operation is defined, class instances are compared by object identity (“address”)

class Derived(int): 
    def __eq__(self, other): 
        print ("Inside  __eq__") 
        return NotImplemented 
 
    def __cmp__(self, other): 
        print ("Inside __cmp__ finally") 
        return True 
 
>>> Derived(12) == Derived(12) 
Inside  __eq__ 
Inside  __eq__ 
Inside __cmp__ finally 
False 

不是让我们定义一个没有定义方法的类:

class Derived(object): 
    pass 
 
>>> Derived() == Derived()   
False 
>>> d = Derived() 
>>> d == d  # Same objects. 
True 

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

#  Python 3.5 
>>> Derived() == Derived() 
False 
>>> d = Derived() 
>>> d == d 
True