2012-04-07 14 views
5

En the manual es dice:métodos mínimos de pedidos con Typing pato en Python 3.1

in general, __lt__() and __eq__() are sufficient, if you want the conventional meanings of the comparison operators

pero veo el error:

>  assert 2 < three 
E  TypeError: unorderable types: int() < IntVar() 

cuando corro esta prueba:

from unittest import TestCase 

class IntVar(object): 

    def __init__(self, value=None): 
     if value is not None: value = int(value) 
     self.value = value 

    def __int__(self): 
     return self.value 

    def __lt__(self, other): 
     return self.value < other 

    def __eq__(self, other): 
     return self.value == other 

    def __hash__(self): 
     return hash(self.value) 

class DynamicTest(TestCase): 

    def test_lt(self): 
     three = IntVar(3) 
     assert three < 4 
     assert 2 < three 
     assert 3 == three 

Me sorprende que cuando IntVar() está a la derecha, __int__() no se está llamando. ¿Qué estoy haciendo mal?

Adición __gt__() reparar este problema, sino que significa que no entiendo cuáles son los requisitos mínimos son para ordenar ...

Gracias, Andrew

+0

Si observa los [métodos de comparación de documentos enriquecidos] (http://docs.python.org/release/3.1.3/reference/datamodel.html#object.__lt__) menciona específicamente este comportamiento: 'Allí no hay versiones de argumentos intercambiados de estos métodos (para usar cuando el argumento de la izquierda no admite la operación pero sí el argumento de la derecha); más bien, __lt __() y __gt __() son reflejo el uno del otro, __le __() y __ge __() son reflejo el uno del otro, y __eq __() y __ne __() son su propio reflejo. Los argumentos para los métodos de comparación ricos nunca se fuerzan. – agf

+0

@agf: Las respuestas deben estar en Respuestas, no en comentarios. –

+0

@EthanFurman Los documentos no lo guían a través del caso específico como lo hace la respuesta de Sven, y la OMI es necesaria para merecer la publicación como una respuesta, no solo como un comentario. – agf

Respuesta

4

3.x Python nunca se va a hacer ningún tipo de coacciones para los operadores , por lo que __int__() no se usa en este contexto. La comparación

a < b 

primero intentará llamar type(a).__lt__(a, b), y si esto vuelve NotImplemented, se llamará type(b).__gt__(b, a).

La cita de la documentación se trata de hacer que las comparaciones funcionen para un solo tipo, y la explicación anterior muestra por qué esto sería suficiente para un solo tipo.

Para hacer el tipo de interactuar correctamente con int, debe o bien poner en práctica todo el operador de comparación, o utilizar el total_ordering decorator disponibles en Python 2.7 o 3.2.

+0

gracias. se había olvidado por completo de total_ordering. eso hará a la perfección. –

+1

total_ordering funciona en su caso. Sin embargo, dos clases diferentes que usan el total_ordering pueden fallar: http://bugs.python.org/issue10042 –