Python文档明确指出了x==y调用x.__eq__(y)。但是似乎在许多情况下,情况恰恰相反。它何时何地发生的原因在哪里记录,如何确定我的对象__cmp__或__eq__方法将被调用。
编辑:只是为了澄清,我知道__eq__在优选中调用__cmp__,但是我不清楚为什么y.__eq__(x)优先于调用x.__eq__(y),而后者是文档状态将发生的原因。
>>> class TestCmp(object):
... def __cmp__(self, other):
... print "__cmp__ got called"
... return 0
...
>>> class TestEq(object):
... def __eq__(self, other):
... print "__eq__ got called"
... return True
...
>>> tc = TestCmp()
>>> te = TestEq()
>>>
>>> 1 == tc
__cmp__ got called
True
>>> tc == 1
__cmp__ got called
True
>>>
>>> 1 == te
__eq__ got called
True
>>> te == 1
__eq__ got called
True
>>>
>>> class TestStrCmp(str):
... def __new__(cls, value):
... return str.__new__(cls, value)
...
... def __cmp__(self, other):
... print "__cmp__ got called"
... return 0
...
>>> class TestStrEq(str):
... def __new__(cls, value):
... return str.__new__(cls, value)
...
... def __eq__(self, other):
... print "__eq__ got called"
... return True
...
>>> tsc = TestStrCmp("a")
>>> tse = TestStrEq("a")
>>>
>>> "b" == tsc
False
>>> tsc == "b"
False
>>>
>>> "b" == tse
__eq__ got called
True
>>> tse == "b"
__eq__ got called
True
编辑:从马克·迪金森的答案和评论中,它看起来像是:
丰富的比较替代 __cmp__
__eq__是它自己的__rop__,以它的__op__(以及类似的__lt__,__ge__等等)
如果左对象是内置类或新样式类,而右对象是其子类,则__rop__在左对象之前尝试右对象__op__
这解释了TestStrCmp示例中的行为。
TestStrCmp是的子类,str但没有实现自己的子类,__eq__因此两种情况下__eq__ofstr优先(例如,由于规则1而tsc
== "b"调用)。b.__eq__(tsc)``__rop__
在TestStrEq示例中,tse.__eq__在两种情况下都被调用,因为它TestStrEq是的子类,str因此优先调用它。
在TestEq示例中,两次TestEq实现(__eq__而int不是__eq__两次)都被调用(规则1)。
但我仍然不了解的第一个示例TestCmp。 tc不是intAFAICT的子类,因此1.__cmp__(tc)应该调用AFAICT ,但不是。