2010-01-27 9 views
5
class x: 
    def __init__(self,name): 
     self.name=name 

    def __str__(self): 
     return self.name 

    def __cmp__(self,other): 
     print("cmp method called with self="+str(self)+",other="+str(other)) 
     return self.name==other.name 
     # return False 


instance1=x("hello") 
instance2=x("there") 

print(instance1==instance2) 
print(instance1.name==instance2.name) 

La salida aquí es:método __cmp__ ¿esto no funciona como se esperaba en Python 2.x?

cmp method called with self=hello,other=there 
True 
False 

que no es lo que esperaba: estoy tratando de decir 'dos ​​instancias son iguales si los campos de nombre son iguales'.

Si simplemente return False de la función __cmp__, esto también se reporta como True !! Si devuelvo -1, obtengo False - pero como estoy tratando de comparar cadenas, no me siento bien.

¿Qué estoy haciendo mal aquí?

Respuesta

9

__cmp__(x,y) debe devolver un número negativo (por ejemplo, -1) si x < y, un número positivo (por ejemplo, 1) si x > y y 0 si x == y. Nunca deberías devolver un booleano con él.

Lo que está sobrecargando es __eq__(x, y).

+0

Gracias - obtienes el tickmark (a pesar de que otras personas proporcionaron información similar), ¡ya que esta es la explicación más clara! – monojohnny

+0

Como otros comentaron, __cmp __() es obsoleto. Defina __lt __(), __eq __() y __gt __() en su lugar. Según http://docs.python.org/dev/whatsnew/3.0.html#ordering-comparisons – smci

2

__cmp__() es obsoleto. Defina __lt__(), __eq__() y __gt__() en su lugar.

Aun así, lo estás haciendo mal. Se supone que debes devolver un número entero.

+0

"obsolescente" ?? ¿De dónde escogiste esto? Las otras existen, pero en la mayoría de los casos tiene más sentido usar __cmp__, en este caso, por ejemplo, tomaría 3 métodos en lugar de solo uno. http://docs.python.org/reference/datamodel.html – jsbueno

+1

@jsbueno: Tercera viñeta: http://docs.python.org/dev/3.0/whatsnew/3.0.html#ordering-comparisons –

+0

La URL se ha movido a http://docs.python.org/dev/whatsnew/3.0.html#ordering-comparisons – smci

5

el método __cmp__ debe devolver -1, 0 o 1, cuando auto < otro, self == other, self> other respectvelly.

Usted puede hacer

return cmp(self.name, other.name) 

en su código para obtener un resultado adecuado

+0

¡Gracias! Resulta que quise decir '__eq__'! – monojohnny

0

de búsqueda de la documentación para __cmp__, estás supone que devuelven un entero:

debe devolver un entero negativo si auto < otro, cero si mismo == otro, un número entero positivo si auto> otra.

4

Estás confundiendo __cmp__ con __eq__.

From the documentation of __cmp__:

debe devolver un entero negativo si mismo < otro, cero si mismo == otro, un número entero positivo si auto> otra.

__eq__ devuelve una regla booleana que determina si dos objetos son iguales __cmp__, devuelve un entero que determina si los dos objetos son mayores o menores que el uno al otro, y así se llama a menos que tenga específico __eq__, __ne__, __le__, __ge__, __lt__ y __gt__ métodos.

En su caso, usted quiere un método __cmp__ en lugar de __eq__, ya que le ahorrará la implementación de los otros 5 métodos para las otras comparaciones.

podría utilizar el cmp() function y poner lo siguiente en su método __cmp__:

return cmp(self.name,other.name) 

Nota, es as highlighted by Ignacio este isn't the preferred method in Python 3.0, pero en Python 2.x __cmp__ es el camino a seguir.

Cuestiones relacionadas