The Python docs clearly state that x==y
calls x.__eq__(y)
. However it seems that under many circumstances, the opposite is true. Where is it documented when or why this happens, and how can I work out for sure whether my object's __cmp__
or __eq__
methods are going to get called.
Edit: Just to clarify, I know that __eq__
is called in preferecne to __cmp__
, but I'm not clear why y.__eq__(x)
is called in preference to x.__eq__(y)
, when the latter is what the docs state will happen.
>>> 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: From Mark Dickinson's answer and comment it would appear that:
__cmp__
__eq__
is it's own __rop__
to it's __op__
(and similar for __lt__
, __ge__
, etc)__rop__
is tried before the left object's __op__
This explains the behaviour in theTestStrCmp
examples. TestStrCmp
is a subclass of str
but doesn't implement its own __eq__
so the __eq__
of str
takes precedence in both cases (ie tsc == "b"
calls b.__eq__(tsc)
as an __rop__
because of rule 1).
In the TestStrEq
examples, tse.__eq__
is called in both instances because TestStrEq
is a subclass of str
and so it is called in preference.
In the TestEq
examples, TestEq
implements __eq__
and int
doesn't so __eq__
gets called both times (rule 1).
But I still don't understand the very first example with TestCmp
. tc
is not a subclass on int
so AFAICT 1.__cmp__(tc)
should be called, but isn't.
Summary. Implement the Python __eq__ method to define the equality logic for comparing two objects using the equal operator ( == )
The '==' is known as the equality operator. The 'is' is known as the identity operator. The == operator helps us compare the equality of objects. The is operator helps us check whether different variables point towards a similar object in the memory.
Python string __contains__() is an instance method and returns boolean value True or False depending on whether the string object contains the specified string object or not. Note that the Python string contains() method is case sensitive.
You're missing a key exception to the usual behaviour: when the right-hand operand is an instance of a subclass of the class of the left-hand operand, the special method for the right-hand operand is called first.
See the documentation at:
http://docs.python.org/reference/datamodel.html#coercion-rules
and in particular, the following two paragraphs:
For objects
x
andy
, firstx.__op__(y)
is tried. If this is not implemented or returnsNotImplemented
,y.__rop__(x)
is tried. If this is also not implemented or returnsNotImplemented
, a TypeError exception is raised. But see the following exception:Exception to the previous item: if the left operand is an instance of a built-in type or a new-style class, and the right operand is an instance of a proper subclass of that type or class and overrides the base’s
__rop__()
method, the right operand’s__rop__()
method is tried before the left operand’s__op__()
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With