Las variables de python son punteros?

Las variables en Python son solo indicadores, que yo sepa.

Según esta regla, puedo asumir que el resultado de este fragmento de código:

i = 5 j = i j = 3 print(i) 

sería 3 . Pero obtuve un resultado inesperado para mí, fue 5 .

Además, mi libro de Python cubre este ejemplo:

 i = [1,2,3] j = i i[0] = 5 print(j) 

El resultado sería [5,2,3] .

¿Qué estoy entendiendo mal?

Los llamamos referencias. Trabajan asi

 i = 5 # create int(5) instance, bind it to i j = i # bind j to the same int as i j = 3 # create int(3) instance, bind it to j print i # i still bound to the int(5), j bound to the int(3) 

Las pequeñas intenciones están internadas, pero eso no es importante para esta explicación.

 i = [1,2,3] # create the list instance, and bind it to i j = i # bind j to the same list as i i[0] = 5 # change the first item of i print j # j is still bound to the same list as i 

Las variables no son punteros. Cuando asigna una variable, está vinculando el nombre a un objeto. Desde ese punto en adelante, puede referirse al objeto usando el nombre, hasta que ese nombre rebote.

En su primer ejemplo, el nombre i está vinculado al valor 5 . La vinculación de valores diferentes al nombre j no tiene ningún efecto en i , por lo que cuando imprima más tarde el valor de i el valor sigue siendo 5 .

En tu segundo ejemplo, vinculas i y j al mismo objeto de lista. Cuando modifica el contenido de la lista, puede ver el cambio independientemente del nombre que use para referirse a la lista.

Tenga en cuenta que sería incorrecto si dijera “ambas listas han cambiado”. Solo hay una lista, pero tiene dos nombres ( i y j ) que se refieren a ella.

Documentación relacionada

  • Modelo de ejecución – Denominación y vinculación

Las variables de Python son nombres vinculados a objetos

De los documentos :

Los nombres se refieren a objetos. Los nombres se introducen mediante operaciones de enlace de nombres. Cada aparición de un nombre en el texto del progtwig se refiere al enlace de ese nombre establecido en el bloque de función más interno que contiene el uso.

Cuando tu lo hagas

 i = 5 j = i 

eso es lo mismo que hacer

 i = 5 j = 5 

j no apunta a i , y después de la asignación, j no sabe que existe. j está simplemente vinculado a lo que estaba señalando en el momento de la asignación.

Si hicieras las tareas en la misma línea, se vería así:

 i = j = 5 

Y el resultado sería exactamente el mismo.

Así, más tarde haciendo.

 i = 3 

no cambia a lo que j apunta, y puede intercambiarlo, j = 3 no cambiaría a lo que apunto.

Tu ejemplo no hace referencia a la lista.

Así que cuando haces esto:

 i = [1,2,3] j = i 

Es lo mismo que hacer esto:

 i = j = [1,2,3] 

así que i y j apuntan a la misma lista. Entonces tu ejemplo muta la lista:

 i[0] = 5 

Las listas de Python son objetos mutables, así que cuando cambias la lista de una referencia y la miras desde otra referencia, verás el mismo resultado porque es la misma lista.

No son punteros, son referencias a objetos. Los objetos pueden ser mutables o inmutables. Un objeto inmutable se copia cuando se modifica. Un objeto mutable se altera en el lugar. Un entero es un objeto inmutable, al que hace referencia por sus variables i y j. Una lista es un objeto mutable.

En tu primer ejemplo

 i=5 # The label i now references 5 j=i # The label j now references what i references j=3 # The label j now references 3 print i # i still references 5 

En tu segundo ejemplo:

 i=[1,2,3] # i references a list object (a mutable object) j=i # j now references the same object as i (they reference the same mutable object) i[0]=5 # sets first element of references object to 5 print j # prints the list object that j references. It's the same one as i. 

Cuando establece j=3 la etiqueta j ya no se aplica (puntos) a i , comienza a apuntar al número entero 3 . El nombre i aún hace referencia al valor que estableció originalmente, 5 .

La asignación no modifica los objetos; Todo lo que hace es cambiar donde apunta la variable. Cambiar donde una variable de puntos no cambiará donde otra variable apunta.

Probablemente esté pensando en el hecho de que los arrays y los diccionarios son tipos mutables. Hay operadores para modificar los objetos reales en el lugar, y si usa uno de ellos, verá el cambio en todas las variables que apuntan al mismo objeto:

 x = [] y = x x.append(1) # x and y both are now [1] 

Pero la asignación sigue moviendo el puntero:

 x = [2] # x is now [2], y is still [1] 

Los números son tipos de valor, lo que significa que los valores reales son inmutables. Si haces x=3; x += 2 x=3; x += 2 , no estás convirtiendo el número 3 en el número 5; solo estás haciendo que x apunte a 5 en lugar de 3. El 3 sigue sin cambiar, y cualquier variable que apunte a él seguirá viendo 3 como su valor.

(En la implementación real, los números probablemente no son tipos de referencia y las variables realmente contienen una representación del valor directamente en lugar de señalarlo, pero esa distinción no cambia la semántica en lo que respecta a los tipos de valor).

cualquier variable que esté en el lado izquierdo del signo ‘=’ se asigna con el valor en el lado derecho de ‘=’

i = 5

j = i — j tiene 5

j = 3 — j tiene 3 (sobrescribe el valor de 5) pero nada ha cambiado con respecto a i

print(i) – entonces esto imprime 5

En Python, todo es objeto, incluidas las piezas de memoria que te devuelven. Eso significa que, cuando se crea una nueva porción de memoria (independientemente de lo que haya creado: int, str, objeto personalizado, etc.), tiene un nuevo objeto de memoria. En su caso, esta es la asignación a 3 que crea un nuevo objeto (memoria) y por lo tanto tiene una nueva dirección.

Si ejecutas lo siguiente, ves lo que quiero decir fácilmente.

 i = 5 j = i print("id of j: {}", id(j)) j = 3 print("id of j: {}", id(j)) 

OMI, en lo que respecta a la memoria, esta es la comprensión / diferencia clave entre C y Python. En C / C ++, se le devuelve un puntero a la memoria (si, por supuesto, utiliza la syntax del puntero) en lugar de un objeto de memoria que le brinda mayor flexibilidad en términos de cambio de la dirección referida.