tutorial lenguaje instalar descargar python

python - lenguaje - ¿Cuál es la diferencia entre la asignación desestructurada y la asignación "normal"?



python wikipedia (2)

Lo que sucede es que el intérprete interactivo de Python compila cada declaración por separado . La compilación no solo produce un código de bytes, sino que también produce constantes para cualquier tipo inmutable incorporado, incluidos los enteros. Esas constantes se almacenan con el objeto de código como el atributo co_consts .

Tu x = -10 se compila por separado de la asignación y = -10 , y terminas con estructuras de co_consts completamente separadas. Su x, y = [-10, -10] asignación iterable por otro lado, es una instrucción de asignación única, que se pasa al compilador de una vez, por lo que el compilador puede reutilizar constantes.

Puedes poner frases simples (como asignaciones) en una sola línea con un punto y coma entre ellas, en cuyo punto, en Python 2.7, obtienes el mismo objeto -10 nuevo:

>>> x = -10; y = -10 >>> x is y True

Aquí compilamos una sola instrucción de nuevo, para que el compilador pueda decidir que solo necesita un único objeto para representar el valor -10 :

>>> compile(''x = -10; y = -10'', '''', ''single'').co_consts (-10, None)

''single'' es el modo de compilación que utiliza el intérprete interactivo. El código de bytes compilado carga el valor -10 de esas constantes.

Obtendrías lo mismo si pusieras todo en una función, compilado como una sola declaración compuesta:

>>> def foo(): ... x = -10 ... y = -10 ... return x is y ... >>> foo() True >>> foo.__code__.co_consts (None, -10)

Los módulos también se compilan en una sola pasada, por lo que los globales de un módulo pueden compartir constantes.

Todo esto es un detalle de implementación . Nunca debes , nunca, contar con esto.

Por ejemplo, en Python 3.6, el operador menos unario se maneja por separado (en lugar de que -10 se vea como un único entero entero), y el valor -10 se alcanza después del plegamiento constante durante la optimización de la mirilla. Esto te permite obtener dos valores separados de -10 :

>>> import sys >>> sys.version_info sys.version_info(major=3, minor=6, micro=3, releaselevel=''final'', serial=0) >>> compile(''x = -10; y = -10'', '''', ''single'').co_consts (10, None, -10, -10)

Otras implementaciones de Python (PyPy, Jython, IronPython, etc.) son libres de manejar las constantes de manera diferente nuevamente.

Esta pregunta ya tiene una respuesta aquí:

Estaba jugando en el Python 2.7.6 REPL y encontré este comportamiento.

>>> x = -10 >>> y = -10 >>> x is y False >>> x, y = [-10, -10] >>> x is y True

Parece que la asignación desestructurada devuelve la misma referencia para valores equivalentes. ¿Por qué es esto?


No sé nada de Python pero tenía curiosidad.

Primero, esto sucede cuando se asigna una matriz también:

x = [-10,-10] x[0] is x[1] # True

También ocurre con las cuerdas, que son inmutables.

x = [''foo'', ''foo''] x[0] is x[1] # True

Desmontaje de la primera función:

0 LOAD_CONST 1 (-10) 3 LOAD_CONST 1 (-10) 6 BUILD_LIST 2 9 STORE_FAST 0 (x)

La LOAD_CONST (consti) empuja constantes constantes co_consts[consti] en la pila. Pero ambas operaciones aquí tienen consti=1 , por lo que el mismo objeto se está empujando a la pila dos veces. Si los números en la matriz fueran diferentes, se desarmaría a esto:

0 LOAD_CONST 1 (-10) 3 LOAD_CONST 2 (-20) 6 BUILD_LIST 2 9 STORE_FAST 0 (x)

Aquí, las constantes de índice 1 y 2 son empujadas.

co_consts es una tupla de constantes usada por un script de Python. Evidentemente, los literales con el mismo valor solo se almacenan una vez.

En cuanto a por qué funciona la asignación "normal": está utilizando el REPL, por lo que asumo que cada línea se compila por separado. Si pones

x = -10 y = -10 print(x is y)

en una secuencia de comandos de prueba, obtendrá True . Así que la asignación normal y la desestructurada funcionan igual en este sentido :)