Python: diferentes resultados al usar PyCharm e IDLE / python

Acabo de leer sobre el ‘resultado inesperado de su operador’ que ocurre porque los números de caché de Python entre -5 y 256.

Esto fue discutido aquí: el operador “is” se comporta inesperadamente con enteros

y aquí: “es” e “id” en Python 3.5

Cuando ejecuto uno de los ejemplos proporcionados allí, obtengo resultados diferentes entre Python Idle y Python IDE (estoy usando la edición profesional Jetbrains Pycharm – 5.0.4).

Cuando se usa Python IDLE, este es el resultado:

a = 1000 b = 1000 print (a is b) # prints False 

cuando se usa Pycharm 5.0.4 este es el resultado:

 a = 1000 b = 1000 print (a is b) # prints True 

¿Cómo podría ser esto? Lo he vuelto a comprobar y el intérprete de Python de mi proyecto es exactamente el mismo en ambos casos (ambos son Python 3.5.1). No estoy seguro de si esto es algo que he hecho mal, y esperaba que alguien pudiera explicarlo.

Editar:

Sé que ‘a’ es ‘b’ == verdadero iff id (a) == id (b), y que puede verificarlo como algunos de ustedes mencionaron en los comentarios. Tal vez debería haber sido más claro, lo que no entiendo es cómo podría ser que un IDE tenga un comportamiento diferente. Pensé (y por favor, corríjame, ya que parece que estoy equivocado) que un IDE es solo un entorno fácil de usar que usa comstackdores / intérpretes externos, y es por eso que son independientes de esos IDE (por ejemplo, pycharm admite no solo Python, y pude ejecutar Eclipse con comstackdor C, o Java, etc. (todos los cuales no son parte del IDE).

Gracias, Alon.

Esto se debe a cómo LOAD_CONST código de byte LOAD_CONST :

Empuja co_consts[consti] en la stack.

Como los enteros se almacenan como constantes, las asignaciones al mismo entero en el mismo contexto darán exactamente el mismo resultado, podemos ver que el argumento de LOAD_CONST es 0 para a y b:

 >>> import dis >>> dis.dis("a = 1000 ; b = 1000") 1 0 LOAD_CONST 0 (1000) 3 STORE_NAME 0 (a) 6 LOAD_CONST 0 (1000) 9 STORE_NAME 1 (b) 12 LOAD_CONST 1 (None) 15 RETURN_VALUE # ^ this is the argument 

donde, como en una sesión interactiva, cada comando se comstack por separado (para que puedan ejecutarse por separado), de modo que las constantes serán diferentes:

 >>> code1 = compile("a = 1000","","exec") >>> code2 = compile("a = 1000","","exec") >>> code1.co_consts, code2.co_consts ((1000, None), (1000, None)) >>> code1.co_consts[0] is code2.co_consts[0] False 

De manera similar, la constante en una función siempre será la misma pero será diferente a la constante en otras funciones:

 def f(): return 1000 def g(): return 1000 #different code object!! #these all work assert f() is f() assert g() is g() assert f() is not g() assert f() is not 1000 and g() is not 1000 

También tenga en cuenta que, como @AniMenon ha señalado, los números de -5 a 256 son singletons para la optimización, por lo que no se mantendrán los números de ese rango.

De la documentación para el operador es :

Los operadores is y is not prueban la identidad del objeto: x is y es verdadero si y solo si x e y son el mismo objeto.

Ahora vamos a revisar IDLE:

 >>> a = 1000 >>> b = 1000 >>> print ( a is b ) False >>> >>> >>> id(a) 35334812 >>> id(b) 35334800 

PyCharm:

 >>> a = 1000 b = 1000 print (a is b) True >>> id(a) 36079236 >>> id(b) 36079236 

En PyCharm, a y b son los mismos objetos que en IDLE no lo son.

Ahora, ¿qué se está introduciendo en PyCharm? Que si ingresa su código línea por línea, como en IDLE, obtendrá los mismos resultados que en IDLE:

 >>> a = 1000 >>> b = 1000 >>> print (a is b) False 

Mi conjetura que

 >>> a = 1000 b = 1000 

está optimizado para:

 >>> a = b = 1000 >>> print (a is b) True 

Por eso tienes el mismo objeto para a y b

devolverá True si dos variables apuntan al mismo objeto, == devolverá True si los objetos a los que hacen referencia las variables son iguales.

En python,

 >>> a = [1, 2, 3] >>> b = a >>> b is a True >>> b == a True >>> b = a[:] >>> b is a False >>> b == a True 

Eso es porque estamos haciendo coincidir el id (a) al id (b).

Considerar,

 a = 1000 b = 1000 a is b 

a is b sería falso; sus suposiciones acerca de la identidad solo se mantienen en CPython para los números en el rango de -5 to 256 inclusive, que son singletons por razones de rendimiento, pero todos los demás bashs se recrean según sea necesario, no singletons.

Basado en: referencia