Die Python-Dokumente geben eindeutig an, dass x==y
x.__eq__(y)
aufruft. Es scheint jedoch, dass unter vielen Umständen das Gegenteil der Fall ist. Wo ist dokumentiert, wann oder warum das passiert und wie kann ich sicher herausfinden, ob die Methoden oder __eq__
meines Objekts aufgerufen werden?Warum/Wenn in Python `x == y` ruft `y .__ eq __ (x)`?
Edit: Nur um zu klären, ich weiß, dass __eq__
in preferecne zu __cmp__
genannt wird, aber ich bin mir nicht klar, warum y.__eq__(x)
in Vorzug x.__eq__(y)
genannt wird, wenn es sich dabei, was der docs Zustand passieren wird.
>>> 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: Von Mark Dickinson Antwort und kommentieren es, dass erscheinen würde:
- Rich-Vergleich überschreibt
__cmp__
__eq__
ist es selbst ist__rop__
es ist__op__
(und ähnlich für__lt__
,__ge__
, etc)- Wenn das linke Objekt eine eingebaute oder neue Stilklasse ist und das Recht eine Unterklasse davon ist, ist das richtige Objekt
__rop__
versucht wird, bevor das linke Objekt der__op__
Dieses Verhalten in den TestStrCmp
Beispiele erläutert. TestStrCmp
ist eine Unterklasse von str
aber nicht implementiert seinen eigenen __eq__
so die __eq__
von str
Vorrang in beiden Fällen nehmen (dh tsc == "b"
nennt b.__eq__(tsc)
als __rop__
wegen Regel 1).
In den TestStrEq
Beispielen tse.__eq__
wird in beiden Fällen genannt, weil TestStrEq
eine Unterklasse von str
ist und so wird es bevorzugt genannt.
In den TestEq
Beispielen TestEq
implementiert __eq__
und int
nicht so __eq__
wird beide Male (Regel 1) genannt.
Aber ich verstehe immer noch nicht das erste Beispiel mit TestCmp
. tc
ist keine Unterklasse auf int
so sollte AFAICT 1.__cmp__(tc)
aufgerufen werden, ist es aber nicht.
@Daniel Pryden: Danke für die Formatierung behoben! Ich werde versuchen, mich beim nächsten Mal an blockquote zu erinnern. –
Schön, aber ich dachte, (aber bin mir nicht sicher), dass alle "__rop__" Methoden veraltet waren. Auch ich benutze keine von ihnen. – Singletoned
Vereinbar, dass Sie keine '__rop__' Methoden verwenden. Die Vergleichsmethoden sind in dieser Hinsicht besonders: "__eq__" ist eine eigene Umkehrung, also lesen Sie "__eq__" für "__op__" und "__rop__". (Ähnlich ist "__ne__" eine eigene Umkehrung, "__le__" ist die Umkehrung von "__ge__", etc.) Andere haben vorher (richtigerweise IMO) kommentiert, dass die Dokumentation hier etwas Arbeit gebrauchen könnte. Ich bin fast sicher, dass die '__rop__' Methoden nicht veraltet sind! –