La creación de las referencias entre etiquetas y objetos se lleva a cabo de la misma forma en todos los modos de asignación, incluso también para el implícito, como, por ejemplo, en el caso de las etiquetas asignadas implícitamente en las instrucciones for:
donde la etiqueta item para cada iteración se refiere al correspondiente objeto incluido en la lista.
Otro caso de asignación implícita es el paso de los argumentos a una función, en el cual las etiquetas utilizadas como parámetros hacen referencia a los respectivos objetos pasados como argumentos, y no a su copia:
En realidad, cuando se realiza la llamada foo(a, b), se llevan a cabo las asignaciones implícitas par1=a y par2=b, y podemos pensar que a será sustituida por el objeto al cual hace referencia, igual que b.
También la definición de una función da lugar a una asignación implícita. La instrucción def crea un objeto función y lo asigna a la etiqueta situada entre la def y los paréntesis:
Con la indexación se obtiene el mismo comportamiento. Por ejemplo, en el código siguiente podemos pensar que mylist[0], mylist[1] y mylist[2] serán sustituidos por los objetos a los cuales hacen referencia:
Objetos mutables e inmutables
Ante dos etiquetas a y b que hacen referencia al mismo objeto, ¿qué ocurre si hacemos una asignación a una de las dos? Espero que nadie diga que será modificado el objeto al cual hacen referencia. Ya hemos dicho que no es posible modificar un objeto con una asignación. Lo que ocurre es que la etiqueta hará referencia al nuevo objeto que se le asignará. Consideremos el siguiente ejemplo:
Las dos etiquetas a y b se refieren al mismo objeto, como se muestra en la Figura 1.6.
Figura 1.6 - Las etiquetas a y b se refieren al mismo objeto, que tiene la identidad 3074330092.
Si ahora realizamos la asignación a = [1, 2, 3, 4], el objeto con identidad 3074330092 no será modificado:
De hecho, ha sido creado un nuevo objeto, que representa la lista [1, 2, 3, 4], que ha sido asignado a la etiqueta a, mientras que la etiqueta b continua haciendo referencia al mismo objeto que antes, como se muestra en la Figura 1.7.
Figura 1.7 - La etiqueta a se refiere a un nuevo objeto, mientras que b continua refiriéndose al objeto anterior.
Llegados a este punto, quizás nos hayamos preguntado lo siguiente: "¿cómo podemos modificar un objeto si no es posible hacerlo con una asignación ni implícita ni explícita?”. La respuesta nos permitirá entender mejor la diferencia entre objetos mutables e inmutables.
Modificación de objetos mutables
Los objetos mutables pueden ser modificados solo de tres maneras: mediante sus métodos, mediante las asignaciones aumentadas y mediante la instrucción del. Por ejemplo, los métodos list.append() y list.sort() de una lista modifican el objeto:
Las asignaciones aumentadas, como se especifica en la PEP-0203, también modifican el objeto:
Por último, la instrucción del, utilizada en un contexto de indexación o fragmentación, permite eliminar los elementos de un objeto contenedor, modificando así dicho objeto:
Si, en cambio, se aplica una simple etiqueta, solo tiene el efecto de eliminarla del namespace:
Cuando un objeto ya no tiene etiquetas que se refieran a él, Python libera la memoria que ocupaba:
NOTA
Los objetos en CPython tienen internamente dos campos: un descriptor de tipo, utilizado para determinar el tipo del objeto, y un contador de referencias, utilizado para saber si el objeto ya no tiene etiquetas que le hagan referencia y, por tanto, si puede ser eliminado de la memoria. Para más detalles: http:// docs.python.org/py3k/c-api/intro.html.
Vamos a aclarar este concepto con ilustraciones. Inicialmente han sido creadas dos etiquetas a y b que hacían referencia al mismo objeto, como muestra la Figura 1.8.
Figura 1.8 - Las dos etiquetas a y b hacen referencia al mismo objeto.
La instrucción del a ha cancelado la etiqueta a, pero la memoria no ha sido liberada por el objeto puesto que todavía había una etiqueta que hacia referencia a él, como se muestra en la Figura 1.9.
Figura 1.9 - La instrucción del a ha eliminado la etiqueta a, pero no el objeto al cual se refería.
En cambio, cuando ha sido cancelada también la etiqueta b, el objeto ya no tenía más etiquetas que le hicieran referencia, por lo que, siendo inutilizable, Python ha ejecutado el método _ _del_ _() y después ha liberado la memoria que ocupaba el objeto.
Inmutabilidad
Los objetos inmutables no tienen métodos que permitan su modificación, incluso ni las asignaciones aumentadas pueden hacerlo:
No existe ningún modo de modificarlos. Por ejemplo, en la siguiente cadena:
si quisiéramos ampliarla, no podríamos hacerlo. Solo podríamos crear un nuevo objeto y asignarlo a la etiqueta s:
Objetos inmutables que contienen objetos mutables