Python 为什么“int.\uuuueq(other)”是一个有效的比较?
以下代码适用于Python 2.7: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()方法调用,我不明白它为什么
>>> 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
number12.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
number12.0
上运行\uuuuuu eq\uuuu
方法,并获得True
对于派生(12)=Deri