Python 为什么“int.\uuuueq(other)”是一个有效的比较?

Python 为什么“int.\uuuueq(other)”是一个有效的比较?,python,python-2.7,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 考虑到self属性没有显式地指定给int.\uuuu eq\uuu()方法调用,我不明白它为什么

以下代码适用于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.\uuuu eq\uuu()
方法调用,我不明白它为什么会起作用

[编辑]

到目前为止的答案表明,这是关于通过
self.\uuuu eq\uuuu(其他)
返回
NotImplemented
,从而调用
other.\uuu eq\uuuu(自身)
。然后
Derived(12)==Derived(12)
我希望是一个不定式递归,但事实并非如此:

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

它之所以有效,是因为
int.\uuuuu eq\uuu()
返回
NotImplemented
,当这种情况发生时,它会导致调用
other.\uuuu eq\uu(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
从 客户的文件:

由二进制特殊方法返回的特殊值 (例如,
\uuu eq\uuu()
\uu lt\uuuu()
\uu添加()
\uuu rsub\uuu()
)等) 指示未针对执行该操作 其他类型;可以通过就地二进制特殊方法返回 (例如,
\uu imul\uu()
\uu i和
等)用于相同目的。它的 真值是真的

注意:当返回
NotImplemented
时,解释器将重试 其他类型上的反射操作,或其他某种回退, 取决于操作员。如果所有尝试的操作都返回 如果未实现,解释器将引发适当的异常


当两个
返回
未实现时会发生什么情况?

Python2和Python3中的行为不同

在Python2中,它首先返回到
\uuu\cmp\uuu
方法,整数具有。它已在Python3中删除

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

如果未定义
\uuuu cmp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
实例按对象标识(“地址”)进行比较

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

class Derived(object):
    pass

>>> Derived() == Derived()  
False
>>> d = Derived()
>>> d == d  # Same objects.
True
Python3不再有
\uuuu cmp\uuuu
方法,但现在它似乎又回到了身份。而且似乎也没有记录在案

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

它之所以有效,是因为
int.\uuuuu eq\uuu()
返回
NotImplemented
,当这种情况发生时,它会导致调用
other.\uuuu eq\uu(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
从 客户的文件:

由二进制特殊方法返回的特殊值 (例如,
\uuu eq\uuu()
\uu lt\uuuu()
\uu添加()
\uuu rsub\uuu()
)等) 指示未针对执行该操作 其他类型;可以通过就地二进制特殊方法返回 (例如,
\uu imul\uu()
\uu i和
等)用于相同目的。它的 真值是真的

注意:当返回
NotImplemented
时,解释器将重试 其他类型上的反射操作,或其他某种回退, 取决于操作员。如果所有尝试的操作都返回 如果未实现,解释器将引发适当的异常


当两个
返回
未实现时会发生什么情况?

Python2和Python3中的行为不同

在Python2中,它首先返回到
\uuu\cmp\uuu
方法,整数具有。它已在Python3中删除

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

如果未定义
\uuuu cmp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
实例按对象标识(“地址”)进行比较

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

class Derived(object):
    pass

>>> Derived() == Derived()  
False
>>> d = Derived()
>>> d == d  # Same objects.
True
Python3不再有
\uuuu cmp\uuuu
方法,但现在它似乎又回到了身份。而且似乎也没有记录在案

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

在Python 2.7中,如果调用
int.\uuuueq\uuuu
,它总是返回
NotImplemented
。例如:

>>> int.__eq__(12.0)
NotImplemented
当您使用
=
运算符时,它将尝试在左侧参数上运行
\uuuuuueq\uuuu
方法,如果它得到
未实现
,它将从右侧参数返回
\uuueq\uuu
方法的结果

在您的示例中,对于
Derived(12)==12.0
,解释器首先尝试
Derived(12)。\uuuuu eq\uuuuu(12.0)
,并获得
未实现。然后在
float
number
12.0
上运行
\uuuuuu eq\uuuu
方法,并获得
True

在您的
Derived(12)==Derived(12)
示例中,可能发生的情况是,由于这两个对象都为其
\uuu eq\uuu
方法返回
NotImplemented
,并且由于
Derived
继承自
int
,解释器返回到对
int
使用
cmp
内置行为(根据,在您问题的另一个答案中链接到)

下面是一个例子来说明您的情况:

class Derived(int):
    def __eq__(self, other):
        print 'Doing eq'
        return NotImplemented
    def __cmp__(self, other):
        print 'doing cmp'
        return 0  # contrived example - don't do this

>>> Derived(12) == Derived(12)
doing eq
doing eq
doing cmp
True

在Python 2.7中,如果调用
int.\uuuueq\uuuu
,它总是返回
NotImplemented
。例如:

>>> int.__eq__(12.0)
NotImplemented
当您使用
=
运算符时,它将尝试在左侧参数上运行
\uuuuuueq\uuuu
方法,如果它得到
未实现
,它将从右侧参数返回
\uuueq\uuu
方法的结果

在您的示例中,对于
Derived(12)==12.0
,解释器首先尝试
Derived(12)。\uuuuu eq\uuuuu(12.0)
,并获得
未实现。然后在
float
number
12.0
上运行
\uuuuuu eq\uuuu
方法,并获得
True

对于
派生(12)=Deri