is compara la identidad de los objetos (es decir, si las variables apuntan a la misma área de memoria).== (operador eq) compara los valores, es decir, si los objetos son iguales en términos de su contenido.is debe usarse para comparar precisamente la identidad (por ejemplo, con None o para objetos singleton), y no para verificar la igualdad de valores.
Ejemplo:
a = [1, 2, 3] b = [1, 2, 3] print(a == b) # True print(a is b) # False c = None d = None print(c is d) # True
Al trabajar con enteros pequeños o cadenas, el intérprete puede usar "internamiento" (objetos en caché), lo que a veces hace que is sea verdadero para valores iguales, pero esto no debería usarse en la lógica del programa.
Pregunta: ¿Qué imprimirá el siguiente código?
a = 256 b = 256 print(a is b) c = 257 d = 257 print(c is d)¿Por qué?
Respuesta:
Para valores de -5 a 256, Python utiliza un grupo de enteros. Los valores en este rango siempre apuntan a los mismos objetos, por lo que a is b devolverá True. 257 está fuera del grupo, por lo que c is d será False (los objetos son independientes).
Historia
En un microservicio, se realizó la verificación de igualdad de cadenas utilizando is en lugar de ==. Debido a las optimizaciones del intérprete, el programa funcionó "establemente" en las pruebas, pero comenzó a fallar después de la recompilación o otros cambios en el entorno.
Un desarrollador utilizó el operador is en lugar de == para comparar números. Esto funcionó para números pequeños (gracias al grupo), pero para números grandes produjo fallos y resultados impredecibles, lo que causó un mal funcionamiento en los cálculos.
En el diseño de un sistema de autorización, se verificó el JSON recibido con is None (correcto), y luego, por analogía, se hizo lo mismo para las cadenas: if status is "ok". Resultó ser un error: a veces la condición no se cumplía, llevando a una lógica de procesamiento de datos incorrecta.