Del manual de Python 2 :
Detalle de implementación de CPython: los objetos de diferentes tipos, excepto los números, están ordenados por sus nombres de tipo; Los objetos del mismo tipo que no admiten una comparación adecuada se ordenan por su dirección.
Cuando ordena dos cadenas o dos tipos numéricos, la ordenación se realiza de la manera esperada (ordenación lexicográfica para cadena, ordenación numérica para enteros).
Cuando solicita un tipo numérico y otro no numérico, el tipo numérico es lo primero.
>>> 5 < 'foo'
True
>>> 5 < (1, 2)
True
>>> 5 < {}
True
>>> 5 < [1, 2]
True
Cuando ordena dos tipos incompatibles donde ninguno es numérico, se ordenan por orden alfabético de sus nombres de tipo:
>>> [1, 2] > 'foo' # 'list' < 'str'
False
>>> (1, 2) > 'foo' # 'tuple' > 'str'
True
>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True
Una excepción son las clases de estilo antiguo que siempre vienen antes que las clases de estilo nuevo.
>>> class Foo: pass # old-style
>>> class Bar(object): pass # new-style
>>> Bar() < Foo()
False
¿Es este comportamiento obligatorio por las especificaciones del lenguaje, o depende de los implementadores?
No hay especificación de idioma . La referencia del lenguaje dice:
De lo contrario, los objetos de diferentes tipos siempre se comparan desiguales y se ordenan de manera consistente pero arbitraria.
Por lo tanto, es un detalle de implementación.
¿Hay diferencias entre alguna de las principales implementaciones de Python?
No puedo responder a esto porque solo he usado la implementación oficial de CPython, pero hay otras implementaciones de Python como PyPy.
¿Hay diferencias entre las versiones del lenguaje Python?
En Python 3.x, el comportamiento ha cambiado para que intentar ordenar un número entero y una cadena genere un error:
>>> '10' > 5
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
'10' > 5
TypeError: unorderable types: str() > int()