Python文檔明確指出x==y
調用x.__eq__(y)
。然而,在許多情況下,情況正好相反。在哪裏記錄何時或爲何發生這種情況,以及如何確定我的對象的__cmp__
或__eq__
方法是否會被調用。爲什麼/在Python中`x == y`調用`y .__ eq __(x)`?
編輯:只是爲了澄清,我知道__eq__
被稱爲preferecne到__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__
所以str
的__eq__
優先在兩種情況下(即tsc == "b"
調用b.__eq__(tsc)
爲__rop__
,因爲規則1)。
在TestStrEq
示例中,在兩個實例中調用tse.__eq__
,因爲TestStrEq
是str
的子類,因此它被優先調用。
在TestEq
例子,TestEq
實現__eq__
和int
不那麼__eq__
被調用兩次(第1條)。
但我仍然不明白TestCmp
的第一個例子。 tc
不是int
的子類,所以應該調用AFAICT 1.__cmp__(tc)
,但不是。
@Daniel Pryden:感謝格式修復!我會盡量記住下次blockquote。 –
不錯,但我認爲,(但我不確定),所有'__rop__'方法都被棄用了。另外我沒有使用任何一個。 – Singletoned
同意你沒有使用任何'__rop__'方法。比較方法在這方面是特殊的:'__eq__'是它自己的反轉,所以'__op__'和'__rop__'都要讀'__eq__'。 (同樣,'__ne__'是它自己的反向,'__le__'是'__ge__'的反向,等等。) 其他人之前已經評論過(正確的IMO)文檔可以在這裏使用一些工作。 我幾乎可以肯定'__rop__'方法不會被棄用! –