Hola, estoy tratando de entender cómo funciona el paso por referencia de Python. tengo un ejemplo:
>>>a = 1 >>>b = 1 >>>id(a);id(b) 140522779858088 140522779858088Esto tiene mucho sentido ya que a y b hacen referencia al mismo valor que tendrían la identidad. Lo que no entiendo muy bien es cómo este ejemplo:
>>>a = 4.4 >>>b = 1.0+3.4 >>>id(a);id(b) 140522778796184 140522778796136Es diferente de este ejemplo:
>>>a = 2 >>>b = 2 + 0 >>>id(a);id(b) 140522779858064 140522779858064¿Es porque en el tercer ejemplo el intérprete ve el objeto 0 int como "Ninguno" y no se reconoce que necesita una identidad diferente del objeto al que hace referencia la variable "a" (2)? Mientras que en el segundo ejemplo, "b" está agregando dos objetos int diferentes y el intérprete está asignando memoria para que se agreguen ambos objetos, lo que le da a la variable "a", una identidad diferente de la variable "b".
En su primer ejemplo, los nombres a y b "hacen referencia" al mismo objeto debido a interning . La declaración de asignación dio como resultado un número entero con la misma id solo porque ha reutilizado un objeto preexistente que ya estaba dando vueltas en la memoria. Ese no es un comportamiento confiable de los números enteros:
>>> a = 257 >>> b = 257 >>> id(a), id(b) (30610608, 30610728)Como se demostró anteriormente, si elige un número entero lo suficientemente grande, se comportará como se comportaron los flotadores en su segundo ejemplo. E internar pequeños enteros es opcional en el lenguaje Python de todos modos, esto resulta ser un detalle de implementación de CPython: es una optimización de rendimiento destinada a evitar la sobrecarga de crear un nuevo objeto. Podemos acelerar las cosas almacenando en caché instancias de enteros de uso común, a costa de una mayor huella de memoria del intérprete de Python.
No piense en "referencia" y "valor" cuando se trata de Python, el modelo que funciona para C realmente no funciona bien aquí. En su lugar, piense en "nombres" y "objetos".

El diagrama anterior ilustra su tercer ejemplo. 2 es un objeto, a y b son nombres. Podemos tener diferentes nombres apuntando a un mismo objeto. Y los objetos pueden existir sin ningún nombre.
Asignar una variable solo adjunta una etiqueta de nombre . Y eliminar una variable solo elimina una etiqueta de nombre . Si tiene esta idea en mente, entonces el modelo de objetos de Python nunca más lo sorprenderá.
Como se indica aquí , CPython almacena en caché números enteros de -5 a 256. Por lo tanto, todas las variables dentro de este rango con el mismo valor comparten la misma identificación (sin embargo, no apostaría por eso para futuras versiones, pero esa es la implementación actual)
No existe tal cosa para los flotantes, probablemente porque hay una "infinidad" de valores posibles (bueno, no infinitos pero grandes debido al punto flotante), por lo que la posibilidad de calcular el mismo valor por diferentes medios es realmente baja en comparación con los números enteros.
>>> a=4.0 >>> b=4.0 >>> a is b FalseLas variables de Python son siempre referencias a objetos. Estos objetos se pueden dividir en objetos mutables e inmutables.
Un tipo mutable se puede modificar sin que se modifique su id, por lo que cada variable que apunte a este objeto se actualizará. Sin embargo, un objeto inmutable no se puede modificar de esta manera, por lo que Python genera un nuevo objeto con los cambios y reasigna la variable para que apunte a este nuevo objeto, por lo que la identificación de la variable antes del cambio no coincidirá con la identificación de la variable después. el cambio.
Los números enteros y flotantes son inmutables, por lo que después de un cambio apuntarán a un objeto diferente y, por lo tanto, tendrán identificadores diferentes.
El problema es que CPython "almacena en caché" algunos valores enteros comunes para que no haya varios objetos con el mismo valor para ahorrar memoria, y 2 es uno de esos enteros almacenados en caché, por lo que cada vez que una variable apunta al entero 2 tendrá la misma identificación (su valor será diferente para diferentes ejecuciones de python).