根据文档(Python 3.8):
默认情况下,通过使用 来
object实现,在比较错误的情况下返回: 。__eq__()isNotImplementedTrue if x is y else NotImplemented
并且:
运算符号与方法名的对应关系如下: [...]
x==y调用x.__eq__(y)
所以我期望
==相当于__eq__()和__eq__返回。然而在下面,比较返回,而返回:NotImplemented====False__eq__()NotImplementedclass Dummy():
def __init__(self, a):
self.a = a
d1 = Dummy(3)
d2 = Dummy(3)
d1 == d2 # False
d1.__eq__(d2) # NotImplemented
Run Code Online (Sandbox Code Playgroud)
为什么?
原因是,如果操作的一侧不能(或不会)提供答案,则另一侧可以在处理此比较时拥有发言权。一个常见的例子是 float/int 比较:
>>> 1 == 1.0
True
>>> (1).__eq__(1.0)
NotImplemented
>>> (1.0).__eq__(1)
True
Run Code Online (Sandbox Code Playgroud)
对于intand float,两者都不是另一个的子类,并且 anint没有任何关于它是否等于 some 的信息float。相等比较由类型处理float。
如果左侧和右侧有不同的类型,并在挂钩中添加一些调试打印输出,则更容易理解:
class Left:
def __eq__(self, other):
print("trying Left.__eq__")
return NotImplemented
class Right:
def __eq__(self, other):
print("trying Right.__eq__")
return True
Run Code Online (Sandbox Code Playgroud)
演示:
>>> d1 = Left()
>>> d2 = Right()
>>> d1.__eq__(d2)
trying Left.__eq__
NotImplemented
>>> d2.__eq__(d1)
trying Right.__eq__
True
>>> d1 == d2 # Left.__eq__ "opts out" of the comparison, Python asks other side
trying Left.__eq__
trying Right.__eq__
True
>>> d2 == d1 # Right.__eq__ returns a result first, Left.__eq__ isn't considered
trying Right.__eq__
True
Run Code Online (Sandbox Code Playgroud)
左侧type(d1).__eq__通过返回选择退出NotImplemented,这使得右侧有处理操作的“第二次机会”。如果左侧返回False而不是返回NotImplemented,Python 根本不会尝试右侧,结果将d1 == d2是False。如果双方都返回NotImplemented,就像在您的Dummy示例中一样,那么对象将被视为不相等,除非它们相同(即相同的实例)。
| 归档时间: |
|
| 查看次数: |
219 次 |
| 最近记录: |