2010-04-05 14 views

Respuesta

40

x is y es diferente de x == y.

x is y es cierto si y sólo si id(x) == id(y) - es decir, x y y tiene que ser uno y el mismo objeto (con los mismos id s).

Para todos los objetos incorporados de Python (como cadenas, listas, dictados, funciones, etc.), si x is y, entonces x == y también es True. Sin embargo, esto no está garantizado en general. Estrictamente hablando, x == y es verdadero si y solo si x.__eq__(y) devuelve True.

Es posible definir un objeto x con un método __eq__ que siempre devuelve False, por ejemplo, y esto causaría x == y a devolver false, incluso si x is y.

Así que la conclusión es, x is y y x == y son pruebas completamente diferentes.

consideran este por ejemplo:

In [1]: 0 is False 
Out[1]: False 

In [2]: 0 == False 
Out[2]: True 

PS. En lugar de

if x is y: 
    return True 
else: 
    return False 

es más Pythonic escribir

return x is y 

Y del mismo modo,

if x == y: 
    return True 
else: 
    return False 

pueden ser sustituidos por

return x == y 
+0

Eso fue realmente útil. ¡Gracias! – ensnare

+0

@ensnare: ¡No hay problema! Me alegro de poder ayudar. – unutbu

+7

Estoy siendo un poco exigente, pero no es correcto que necesite 'x == y' para que sea verdadero antes de que' x is y' pueda ser verdad. Son pruebas independientes. Es cierto que en la práctica sería difícil encontrar un contraejemplo sensato, pero el método especial '__eq__' podría simplemente devolver' False' o generar una excepción. –

4

Depende. is y is not hacen la comparación de identidad, que es válida para None, Ellipsis, o para asegurarse de que dos objetos son iguales. De lo contrario, use == o !=.

15

x is y compara las identidades de los dos objetos , y está pidiendo 'son x y y nombres diferentes para el mismo objeto?' Es equivalente a id(x) == id(y).

x == y utiliza el operador de igualdad y hace la pregunta más flojo 'son x y y iguales?' Para tipos definidos por el usuario es equivalente a x.__eq__(y).

El método especial __eq__ debe representar 'igualdad' para los objetos, por ejemplo, una clase que represente fracciones querría 1/2 para igual a 2/4, aunque el objeto 'una mitad' no podría tener la misma identidad que el objeto 'dos ​​cuartos'.

Tenga en cuenta que no es solo el caso de que a == b no implique a is b, sino que también ocurre lo contrario. Uno no es en general un requisito más estricto que el otro. Sí, esto significa que usted puede tener a == a retorno False si realmente quiere, por ejemplo:

>>> a = float('nan') 
>>> a is a 
True 
>>> a == a 
False 

Aunque en la práctica es is casi siempre una comparación más específica que ==.

+6

El ejemplo de fracciones está realmente en el lugar, Great Scott. :) – tzot

9
  • == y != son objeto valor operadores de comparación
  • is y is not son objeto identidad operadores de comparación

como otros ya hemos dicho, is (y is not) sólo cuando realmente atención que un par de variables se refiere a exactamente el mismo objeto. en la mayoría de los casos, realmente no le importa en absoluto, por lo que usaría == y !=.

Sin embargo, lo que puede comenzar a notar, si nos fijamos en una gran cantidad de código Python, es que is (y is not) son más susceptibles de ser utilizados cuando se comparan contra True, False, y None. la razón principal de esto es que esos objetos son singletons, lo que significa que hay exactamente una instancia de cada uno de esos valores. ¿Por que importa? bueno, esto lleva a otra razón ... velocidad.

con == y !=, el intérprete tiene que tirar hacia arriba y ambas se denominarán objetos con el fin de hacer una comparación (ya sean de la misma o no), mientras que is y is not simplemente verifica los valores de los objetos a los que se refieren. Dicho esto, puede ver que el último par funcionará más rápido porque no tiene que buscar los objetos para hacer la comparación. Aquí hay una prueba de velocidad de hace un par de años en la que concluimos que, para los one-offs, no es gran cosa, pero si se llama un trillón de veces en un circuito cerrado, bueno, comenzará a sumarse.

http://mail.python.org/pipermail/tutor/2008-June/062708.html

conclusión es que se puede utilizar comparaciones de identidad de objeto para comprobar contra True, False, y None, y todo lo demás debe utilizar operadores de igualdad rectas arriba. no entraremos en enteros enteros ni en métodos de instancia enlazados, ni nada de eso aquí. :-)

+0

Buen punto acerca de la comparación de singletons. En el tema de la velocidad, vale la pena señalar que 'si a == True:' es más lento que 'si a es True:' que a su vez es más lento que 'si a:' (al menos para los tipos incorporados en mis pruebas) A menudo, simplemente usar 'a' o 'no a' es la opción más rápida, aunque no son semánticamente lo mismo que 'a es Verdadero' o 'a es Ninguno', etc. –

+0

Entonces, ¿qué hay de comparar ents, como '1 es 1' o '1 == 1'? –

+0

aunque ambos son equivalentes cuando se usan pequeños ints (actualmente) en el 'rango (-5, 256)', esos no son números publicitados y pueden cambiar en cualquier versión, por lo que es más seguro usar '==' en todos casos excepto 'None',' True', y 'False' (y tal vez algunos otros). – wescpy

Cuestiones relacionadas