Reputation: 8907
Recently I read the "Fluent python" and understood how ==
operator works with python objects, using __eq__()
method. But how it works with int
instances in python2?
>>> a = 1
>>> b = 1
>>> a == b
True
>>> a.__eq__(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__eq__'
in python3 all a.__eq__(b)
returns True
Upvotes: 15
Views: 1334
Reputation: 147
Here's my answer.
import sys
SPECIAL_OPNAMES = \
{ '__eq__': (lambda *args, **kwargs: not cmp(*args, **kwargs)) \
, '__ne__': (lambda *args, **kwargs: cmp(*args, **kwargs)) \
, '__lt__': (lambda *args, **kwargs: cmp(*args, **kwargs) < 0) \
, '__ge__': (lambda *args, **kwargs: cmp(*args, **kwargs) >= 0) \
, '__gt__': (lambda *args, **kwargs: cmp(*args, **kwargs) > 0) \
, '__le__': (lambda *args, **kwargs: cmp(*args, **kwargs) <= 0) \
} if sys.version_info.major == 2 else \
{}
Working example:
>>> item = 1
>>> opname = '__eq__'
>>> t = type(item)
>>> op = SPECIAL_OPNAMES[opname] if opname in SPECIAL_OPNAMES else getattr(t, opname)
>>> op(item, 1)
True
Upvotes: 0
Reputation: 298430
Python prefers to use rich comparison functions (__eq__
, __lt__
, __ne__
, etc.), but if those don't exist, it falls back to using a single comparison function (__cmp__
, removed in Python 3):
These are the so-called “rich comparison” methods, and are called for comparison operators in preference to
__cmp__()
below.
The Python 2 integer type doesn't implement a rich comparison function:
PyTypeObject PyInt_Type = {
...
(cmpfunc)int_compare, /* tp_compare */
...
0, /* tp_richcompare */
In Python 3, the integer type (now a long) implements only a rich comparison function, since Python 3 dropped support for __cmp__
:
PyTypeObject PyLong_Type = {
...
long_richcompare, /* tp_richcompare */
This is why (123).__eq__
doesn't exist. Instead, Python 2 falls back to (123).__cmp__
when testing the equality of two integers:
>>> (1).__eq__(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__eq__'
>>> (1).__cmp__(2)
-1
Upvotes: 10
Reputation: 149
In Python 2, the int
object uses the __cmp__()
method instead of the rich methods like __eq__()
, __lt__()
, __gt__()
, and others.
Upvotes: 6