5

In Python 2.x, the following code produces an error, as expected:

>>> def a(x): return x+3 
...
>>> a+4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'function' and 'int'

However, the following is allowed:

>>> a < 4
False

Why is the + operator not defined for function and int, but the < operator is?

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
Brian Minton
  • 3,377
  • 3
  • 35
  • 41
  • 2
    Just a note: this will give you `TypeError: unorderable types: function() < int()` on Py3k – vaultah May 16 '14 at 16:31
  • Related: http://stackoverflow.com/questions/4084243/clarification-on-comparing-objects-of-different-types – John Y May 16 '14 at 16:31
  • Also http://stackoverflow.com/questions/18516827/why-does-0-evaluate-to-true-in-python/ – devnull May 16 '14 at 16:39
  • _related:_ http://stackoverflow.com/questions/15451472/can-i-make-python-throw-exception-when-equal-comparing-different-data-types/ – devnull May 16 '14 at 16:40
  • http://stackoverflow.com/questions/18387938/how-do-python-comparison-operators-and-work-with-a-function-name-as-an-opera – devnull May 16 '14 at 16:44
  • @devnull: Now I don't know which one to pick anymore. Which one would you regard as canonical? – Martijn Pieters May 16 '14 at 16:56

1 Answers1

14

In Python 2, objects are orderable by default. Types have to explicitly opt out (e.g. complex raises an exception when you try to make greater or lesser than comparisons).

CPython (the original Python implentation) orders None before numbers, then numbers before everything else. Objects that don't implement ordering themselves, are compared by their type name; so function sorts before instances of the class Zippedeedoodah. Other implementations are free to pick different orders.

Python does this to support sorting of heterogeneous lists. Quoting the Value comparisons documenation:

The operators <, >, ==, >=, <=, and != compare the values of two objects. The objects do not need to have the same type.

The default order comparison (<, >, <=, and >=) gives a consistent but arbitrary order.

In Python 3, only objects that explicitly support ordering are supported, everything else throws an exception:

>>> def a(x): return x+3 
... 
>>> a < 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: function() < int()
wim
  • 338,267
  • 99
  • 616
  • 750
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • +1. I missed posts like this. Concise, thorough and easy to understand. – vaultah May 16 '14 at 16:34
  • Can you provide a link to documentation about this? – Brian Minton May 16 '14 at 16:35
  • 1
    @BrianMinton: see the [Comparisons section](https://docs.python.org/2/reference/expressions.html#not-in) of the reference manual. – Martijn Pieters May 16 '14 at 16:38
  • The first line is inaccurate: the `complex` type is not orderable. – wim Oct 19 '20 at 18:57
  • @wim they indeed explicitly throw exceptions when used in comparisons. Sets are also problematic in that those do not support total ordering. I guess it is better to say that the default implementation is for all objects to orderable. – Martijn Pieters Oct 19 '20 at 23:51