Dokumentacja Pythona wyraźnie stwierdza, że x==y
dzwoni pod numer x.__eq__(y)
. Wydaje się jednak, że w wielu okolicznościach jest odwrotnie. Gdzie jest udokumentowane, kiedy i dlaczego tak się dzieje, i jak mogę się upewnić, czy zostaną wywołane metody mojego obiektu? __cmp__
lub __eq__
.Dlaczego/Kiedy w Pythonie występuje `x == y` wywołanie` y .__ eq __ (x) `?
Edit: Właśnie w celu wyjaśnienia, wiem, że __eq__
nazywa się preferecne do __cmp__
, ale nie jestem jasne, dlaczego y.__eq__(x)
nazywa zamiast do x.__eq__(y)
, gdy ten ostatni jest co państwo docs stanie.
>>> 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
Edit: Z odpowiedzi Mark Dickinson i komentarz wydaje się, że:
- Rich porównanie nadpisuje
__cmp__
__eq__
jest to własny__rop__
aby to__op__
(i podobny do__lt__
,__ge__
, etc)- Jeśli lewy obiekt jest klasą wbudowaną lub stylem nowym, a prawa jest jego podklasą, właściwy obiekt
__rop__
jest sądzony przed lewa obiektu__op__
To wyjaśnia zachowanie w przykładach TestStrCmp
. TestStrCmp
jest podklasą str
, ale nie implementuje własnego __eq__
, więc __eq__
z str
ma pierwszeństwo w obu przypadkach (tj. tsc == "b"
dzwoni b.__eq__(tsc)
jako __rop__
z powodu reguły 1).
W przykładach TestStrEq
w obu przypadkach wywoływana jest nazwa tse.__eq__
, ponieważ TestStrEq
jest podklasą str
i dlatego jest wywoływana w preferencjach.
W przykładach TestEq
, TestEq
realizuje __eq__
i int
nie tak __eq__
jest wywoływana za każdym razem (zasada 1).
Ale nadal nie rozumiem pierwszego przykładu z TestCmp
. tc
nie jest podklasą na int
, więc AFAICT 1.__cmp__(tc)
powinien zostać wywołany, ale nim nie jest.
@ Daniel Pryden: Dzięki za poprawki formatowania! Postaram się zapamiętać cytat następnego razu. –
Niezły, ale myślałem (ale nie jestem pewien), że wszystkie metody "__rop__" były przestarzałe. Również nie używam żadnego z nich. – Singletoned
Uzgodniono, że nie używasz żadnej metody "__rop__". Metody porównania są szczególne pod tym względem: '__eq__' jest własnym odwróceniem, więc przeczytaj' __eq__' zarówno dla '__op__' i' __rop__'. (Podobnie, '__ne__' jest własnym odwróceniem,' __le__' jest odwrotnością '__ge__', itp.) Inni już wcześniej skomentowali (poprawnie, IMO), że dokumentacja mogłaby wykorzystać trochę pracy tutaj. Jestem prawie pewien, że metody "__rop__" nie są przestarzałe! –