1

In python 2 or 3 the built-in classes have the special method defined explicitly. Explicit is better than implicit and all that jazz.

5. > 4.
# True
(5.).__ge__(4.)
# True

But in python 2 there are exceptions for some methods, at least in the integers.

5 > 4
# True
(5).__ge__(4)
# AttributeError: 'int' object has no attribute '__ge__'
# But not all of them fail!
(5).__add__(4)
# 9

What is the cause behind this behavior? Why was it designed this way?

I am using Python 2.7.12

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
durum
  • 3,316
  • 1
  • 25
  • 30

1 Answers1

1

The data model has been updated between and . In one could use the __cmp__ method:

object.__cmp__(self, other)

Called by comparison operations if rich comparison (see above) is not defined. Should return a negative integer if self < other, zero if self == other, a positive integer if self > other. If no __cmp__(), __eq__() or __ne__() operation is defined, class instances are compared by object identity ("address"). See also the description of __hash__() for some important notes on creating hashable objects which support custom comparison operations and are usable as dictionary keys. (Note: the restriction that exceptions are not propagated by __cmp__() has been removed since Python 1.5.)

(formatting added)

The rich comparison operators are the __le__, __ge__, etc.. So in there was an additional fallback mechanism. This is defined for an int, as you can see with:

>>> (2).__cmp__
<method-wrapper '__cmp__' of int object at 0x13ee140>
>>> (2).__cmp__(3)
-1

(Python 2.7.12)

Furthermore offers a cmp(..) builtin function:

cmp(x, y)

Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.

(formatting added)

In , the __cmp__ has been removed as you can read in the What’s New In Python 3.0:

The cmp() function should be treated as gone, and the __cmp__() special method is no longer supported. Use __lt__() for sorting, __eq__() with __hash__(), and other rich comparisons as needed. (If you really need the cmp() functionality, you could use the expression (a > b) - (a < b) as the equivalent for cmp(a, b).)

(formatting added)

This mechanism is not just a wrapper around __cmp__: it will first look whether there are rich comparisons and if not fallback on __cmp__ itself.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • You are right! So for some reason the `int` class was never updated when the new methods arrived. – durum Mar 27 '17 at 13:58
  • @durum: In Python-3.x, `int` has only a `__le__`, etc., not a `__cmp__` so it has been updated. Are you sure you run this in Python-3.x? – Willem Van Onsem Mar 27 '17 at 13:59
  • I was talking about python-2x. Floats were updated in python-2x, but not integers. – durum Mar 27 '17 at 14:04
  • 1
    @durum: well in Python-2.0 you only had `__cmp__` later (but still in Python-2.x) they added `__le__`, etc. You can indeed claim the implemented `__le__`, etc. for floats but for some reason - I don't know - sticked to `__cmp__` for `int`s, that's correct. – Willem Van Onsem Mar 27 '17 at 14:11