una tipos sentencias leer imprimir funciones entrada declarar datos como cadena python variables object

tipos - ¿Qué sucede cuando asigna el valor de una variable a otra variable en Python?



sentencias en python (8)

A mi modo de ver, hay diferentes puntos de vista de un idioma.

  • La perspectiva del "abogado de idiomas".
  • La perspectiva del "programador práctico".
  • la perspectiva del "implementador".

Desde la perspectiva del abogado del lenguaje, las variables de Python siempre "apuntan" a un objeto. Sin embargo, a diferencia de Java y C ++, el comportamiento de == <=> = etc. depende del tipo de tiempo de ejecución de los objetos a los que apuntan las variables. Además, en python la gestión de memoria es manejada por el lenguaje.

Desde una perspectiva práctica del programador, podemos tratar el hecho de que los enteros, cadenas, tuplas, etc. son objetos inmutables * en lugar de valores rectos como un detalle irrelevante. La excepción es cuando se almacenan grandes cantidades de datos numéricos, es posible que deseemos usar tipos que puedan almacenar los valores directamente (por ejemplo, matrices numpy) en lugar de tipos que terminarán con una matriz llena de referencias a objetos pequeños.

Desde la perspectiva de los implementadores, la mayoría de los lenguajes tienen algún tipo de regla tal que si los comportamientos especificados son correctos, la implementación es correcta independientemente de cómo se hagan las cosas realmente.

Entonces sí, su explicación es correcta desde la perspectiva de un abogado de idiomas. Su libro es correcto desde una perspectiva práctica del programador. Lo que realmente hace una implementación depende de la implementación. En cpython, los enteros son objetos reales, aunque los enteros de pequeño valor se toman de un grupo de caché en lugar de crearse de nuevo. No estoy seguro de lo que hacen las otras implementaciones (por ejemplo, pypy y jython).

* Tenga en cuenta la distinción entre objetos mutables e inmutables aquí. Con un objeto mutable, debemos tener cuidado al tratarlo "como un valor" porque algún otro código podría mutarlo. Con un objeto inmutable no tenemos tales preocupaciones.

Este es mi segundo día de aprendizaje de Python (conozco los conceptos básicos de C ++ y algunos OOP), y tengo una ligera confusión con respecto a las variables en Python.

Así es como los entiendo actualmente:

Las variables de Python son referencias (¿o punteros?) A objetos (que son mutables o inmutables). Cuando tenemos algo como num = 5 , el objeto inmutable 5 se crea en algún lugar de la memoria, y el par de referencia nombre-objeto num se crea en un determinado espacio de nombres. Cuando tenemos a = num , no se copia nada, pero ahora ambas variables se refieren al mismo objeto y a se agrega al mismo espacio de nombres.

Aquí es donde mi libro, Automatizar las cosas aburridas con Python , me confunde. Como es un libro para novatos, no menciona objetos, espacios de nombres, etc., e intenta explicar el siguiente código:

>>> spam = 42 >>> cheese = spam >>> spam = 100 >>> spam 100 >>> cheese 42

La explicación que ofrece es exactamente la misma que la de un libro de C ++, que no me agrada porque estamos tratando con referencias / punteros a objetos. Entonces, en este caso, supongo que en la tercera línea, como los enteros son inmutables, al spam se le asigna un puntero / referencia completamente nuevo a una ubicación diferente en la memoria, es decir, la memoria a la que apuntaba inicialmente no se modificó. Por lo tanto, tenemos cheese refiere al objeto inicial al que hace referencia el spam . ¿Es esta la explicación correcta?


Como @DeepSpace mencionó en los comentarios, Ned Batchelder hace un gran trabajo desmitificando variables (nombres) y asignaciones de valores en un blog, desde el cual pronunció una charla en PyCon 2015, Facts and Myths sobre los nombres y valores de Python . Puede ser perspicaz para Pythonistas en cualquier nivel de dominio.


Como desarrollador de C ++, puede pensar en las variables de Python como punteros.

Por lo tanto, cuando escribe spam = 100 , esto significa que "asigna el puntero", que anteriormente apuntaba al objeto 42 , para señalar el objeto 100 .

Anteriormente, a cheese se le asignó que señalara el mismo objeto que señalaba el spam , que en ese momento era 42 . Como no ha modificado el cheese , todavía apunta a 42 .

La inmutabilidad no tiene nada que ver con esto en este caso, ya que la asignación del puntero no cambia nada sobre el objeto al que se apunta.


Cuando almacena spam = 42 , crea un objeto en la memoria. Luego se asigna cheese = spam . Asigna el objeto al que hace referencia el spam a cheese . Y finalmente, cuando cambia el spam = 100 , solo cambia el objeto de spam . Entonces cheese = 42 .


Cuando ejecuta spam = 100 python, cree un objeto más en la memoria pero no cambie el existente. así que todavía tienes cheese puntero a 42 y spam a 100


Es correcto que puedas más o menos cosa de variables como punteros. Sin embargo, el código de ejemplo sería de gran ayuda para explicar cómo funciona esto realmente.

Primero, utilizaremos en gran medida la función id :

Devuelve la "identidad" de un objeto. Este es un número entero que se garantiza que es único y constante para este objeto durante su vida útil. Dos objetos con vidas que no se superponen pueden tener el mismo valor id ().

Es probable que esto devuelva diferentes valores absolutos en su máquina.

Considere este ejemplo:

>>> foo = ''a string'' >>> id(foo) 4565302640 >>> bar = ''a different string'' >>> id(bar) 4565321816 >>> bar = foo >>> id(bar) == id(foo) True >>> id(bar) 4565302640

Puedes ver eso:

  • El foo / bar original tiene diferentes identificadores, porque apuntan a diferentes objetos
  • Cuando la barra se asigna a foo, sus identificadores ahora son los mismos. Esto es similar a que ambos apuntan a la misma ubicación en la memoria que ves al hacer un puntero C ++

cuando cambiamos el valor de foo, se asigna a una identificación diferente:

>>> foo = 42 >>> id(foo) 4561661488 >>> foo = ''oh no'' >>> id(foo) 4565257832

Una observación interesante también es que los enteros tienen implícitamente esta funcionalidad hasta 256:

>>> a = 100 >>> b = 100 >>> c = 100 >>> id(a) == id(b) == id(c) True

Sin embargo, más allá de 256 esto ya no es cierto:

>>> a = 256 >>> b = 256 >>> id(a) == id(b) True >>> a = 257 >>> b = 257 >>> id(a) == id(b) False

sin embargo, asignar aa b mantendrá la identificación igual que se muestra antes:

>>> a = b >>> id(a) == id(b) True


Lo que sucede en el spam = 100 líneas es el reemplazo del valor anterior (puntero al objeto de tipo int con valor 42 ) con otro puntero a otro objeto (tipo int , valor 100 )


Python no es ni pasa por referencia ni pasa por valor. Las variables de Python no son punteros, no son referencias, no son valores. Las variables de Python son nombres .

Piense en ello como "paso por alias" si necesita el mismo tipo de frase, o posiblemente "paso por objeto", porque puede mutar el mismo objeto de cualquier variable que lo indique, si es mutable, pero la reasignación de una variable (alias) solo cambia esa variable.

Si ayuda: las variables C son cuadros en los que escribe valores. Los nombres de Python son etiquetas que pones en valores.

El nombre de una variable de Python es una clave en el espacio de nombres global (o local), que es efectivamente un diccionario. El valor subyacente es algún objeto en la memoria. La asignación le da un nombre a ese objeto. La asignación de una variable a otra variable significa que ambas variables son nombres para el mismo objeto. La reasignación de una variable cambia qué objeto es nombrado por esa variable sin cambiar la otra variable. Ha movido la etiqueta pero no ha cambiado el objeto anterior ni ninguna otra etiqueta.

En el código C subyacente de la implementación de CPython, cada objeto de Python es un PyObject* , por lo que puede pensar que funciona como C si solo tuvo punteros a los datos (sin punteros a punteros, sin valores pasados ​​directamente) .

se podría decir que Python es paso por valor, donde los valores son punteros ... o se podría decir que Python es paso por referencia, donde las referencias son copias.