Los resultados de la terminal interactiva de Python son inconsistentes con los resultados del script

Resultados de terminal interactivos:

In [11]: a=1111111111111111111111111111111111111111111111111111 In [12]: b=1111111111111111111111111111111111111111111111111111 In [13]: a is b Out[13]: False 

resultados del guión:

 # macr0phag3 in ~ [13:55:16] » python -c "a=1111111111111111111111111111111111111111111111111111;b=1111111111111111111111111111111111111111111111111111; print a is b" True 

Emmmmm. Creo que el resultado debería ser Falso … Porque 1111111111111111111111111111111111111111111111111111 es mucho más grande que 256

is no es una prueba de igualdad. Pero, cuando Python declara una variable (tipo inmutable), como b = 1 , descubrirá si el objeto ha sido declarado en el objeto anterior ( a = 1 ). Si se declara el objeto ( a = 1 ), la variable apuntará directamente al objeto anterior y no se aplicará para el nuevo espacio de memoria ( a is b es True )

 In [2]: a=1 In [3]: b=1 In [4]: a is b Out[4]: True 

emmmm ¿Correcto?

En cuanto a “es”, el operador se comporta inesperadamente con los enteros . Explica el uso de is , pero aún no entiendo por qué estos dos métodos conducen a resultados diferentes. 🙁

Tal vez, solo depende de la implementación de Python y del entorno de ejecución.

Realmente depende de lo que estés buscando. El uso is para pruebas de identidad y == para pruebas de igualdad. No confiar en is comprobar la igualdad.

La igualdad se refiere al valor del objeto, mientras que la identidad se refiere al puntero a la misma identificación del objeto. Por ejemplo, si ejecuta esto en su terminal, devuelve False :

 a = 1111 b = int('1111') print(a == b) >>True print(a is b) >>False 

La suposición de uso no is para la prueba de identidad, no se recomienda y su comportamiento depende de la implementación de Python y del entorno de ejecución. De alguna manera, también sospecho que Python lee sus números enteros donde se repiten. Para un ejemplo más:

 a = 257 b = 257 a is b >>False 

De los documentos:

Valor de retorno: Nueva referencia. Crea un nuevo objeto entero con un valor de ival.

La implementación actual mantiene una matriz de objetos enteros para todos los enteros entre -5 y 256, cuando creas un int en ese rango, en realidad simplemente recuperas una referencia al objeto existente. Por lo tanto, debería ser posible cambiar el valor de 1. Sospecho que el comportamiento de Python en este caso no está definido. 🙂

Para la optimización, los enteros cortos en realidad solo hacen referencia al mismo objeto, esto también debería aplicarse si cambia un número único en su valor (no repetido) por encima de 256 , devolverá False .

funciona al comparar el objeto al que se hace referencia para ver si los operandos apuntan al mismo objeto.

De la documentación: es

 The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. x is not y yields the inverse truth value. In [925]: a=1111111111111111111111111111111111111111111111111111 In [926]: b=1111111111111111111111111111111111111111111111111111 In [927]: a is b Out[927]: False In [929]: c = a In [930]: a is c Out[930]: True 

Esto es interesante.

 Python 3.7.1 (default, Oct 22 2018, 11:21:55) Type 'copyright', 'credits' or 'license' for more information IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help. In [1]: a=1111111111111111111111111111111111111111111111111111 In [2]: b=1111111111111111111111111111111111111111111111111111 In [3]: id(a),id(b) Out[3]: (139945897647488, 139945897647536) In [4]: len(str(a)) Out[4]: 52