paso de Variables por referencia a funciones

Daniel Ripolles (Eru) ripolles en aditel.org
Jue Oct 23 02:53:32 CEST 2003


El Miércoles, 22 de Octubre de 2003 22:48, Hernan Martínez Foffani escribió:

> lo de mutabilidad es correcto. y decís bien en tu tutorial que
> es un concepto importante que no se explica mucho.
> lo de "cambiarlos de sitio" no me gusta tanto porque parecería
> que es el mismo objeto que se está moviendo y no es así.
>
> ej:
> >>> x = 4
> >>> y = 5
> >>> z = x + 1
> >>> id(x)
>
> 7954432
>
> >>> id(y)
>
> 7954240
>
> >>> id(z)
>
> 7954240
>
>
> en palabras:
>  - se creó el objeto "4", se lo asoció con el nombre "x".
>  - se creó el objeto "5", se lo asoció con el nombre "y".
>  - la expresion devolvió el objeto "5", se lo asoció a "z"
> el objeto "5" es el mismo tanto en "y" como en "z" no fue
> creado, ni movido, ni copiado en la línea "z=x+1".
> el objeto "4" no se cambio al "5", los dos siguen vivos.
>
> es un comportamiento particular, no tiene que ver con mutabilidad,
> pero que es facil de explicar con la abstraccion "Nombre asociado_a
> Objeto".

En realidad creo que es un poco más complejo aún. Si usamos numeros más 
grandes:

>>> x,y = 100,103
>>> id(x),id(y)
(135734504, 135734516)
>>> z = x + 3
>>> id(z) == id(y)
False
>>> z == y
True

Y lo "grandes" que han de ser estos números para que "un 103" no se almacene 
físicamente en el mismo sitio que "otro 103", si no recuerdo mal, depende de 
la implementación[1]. Por eso me gusta pensar más bien en el comportamiendo 
de los "números grandes", ya que según leí, el hecho de que la "y" y la "z" 
de tu ejemplo "apunten" al mismo sitio es puramente accidental (tema de 
implementación para optimización) y no se debe confiar en ello como un 
"feature". 

De todas formas quizá no me expliqué muy bien. Lo que quise decir es que un 
objeto mutable (por ejemplo una lista) cambia de valor (puede crecer, 
decrecer, cambiar sus elementos) sin que su id() cambie. Esto no es posible 
con un objeto inmutable porque es imprescindible utilizar una asignación (por 
ejemplo, x = x+1), lo que hace que "x" deje de "apuntar" a su antiguo valor y 
ahora "apunte" a uno nuevo.

> si ese concepto es complicado para un no iniciado se
> puede usar la idea de "muebles" (objetos) y "postit" (nombres)
> pegar una etiqueta a un mueble es enlazar el nombre con el
> objeto. un monitor por ejemplo, puede tener pegados muchos postit
> pero para cambiarlo debo quitarle primero todas las etiquetas pegadas
> (inmutabilidad). a los "cajones" (colecciones) también se les pueden
> pegar etiquetas pero puedo poner o quitar cosas dentro sin tener que
> cambiar de postit (mutabilidad). cualquier "cosa" que no tenga
> pegada una etiqueta es pasible de ser recolectada por el ordenanza.
> y así..
>

Muy buena la analogía  para explicar todo este embrollo de una forma menos 
abstracta. Me la apunto :)

> por eso insisto que es preferible cambiar de chip y dejar de pensar
> en variables, pasar por valor, etc. etc.
> o mejor dicho, al principio se puede programar tranquilamente en
> python como si estuvieras programando en basic. pero cuando algunas
> cosillas no funcionan como esperas ahí sí es mejor cambiar el chip.

Amén.

[1] Parece ser que Python crea nada más "arrancar" el espacio físico para un 
número reducido de enteros (creo que 100), sobre todo para evitarse las 
reservas de memoria en tiempo de ejecución, dado que considera que son unos 
valores muy usados y vale la pena "inicializar su memoria" desde el 
principio. (Esto no lo recuero muy bien pero creo que era más o menos así).
-- 
Daniel Ripolles ( Eru )
perl -e '$SIG{__WARN__}=sub{$_||=pop;
s,o.*,$^X,,s$/.*/$$,print};++$^W;m||'




Más información sobre la lista de distribución Python-es