Variables (3)

En esta lección se comentan aspectos avanzados de las variables.

Objetos: identificador, tipo y valor

En Python, cada dato (número, cadena, lista, etc.) que aparece en un programa es un objeto. Cada objeto tiene un identificador, un tipo y un valor:

Creación y destrucción de objetos

Python crea los objetos a medida que se necesitan y los destruye cuando ya no necesitan (y ninguna variable hace referencia a ellos).

Cuando se destuye y crea un nuevo objeto, el identificador puede o no coincidir con identificadores utilizados anteriormente

En Windows, en el caso de los números enteros pequeños Python parece no destruir los objetos (o puede que les asigne el mismo identificador). En el ejemplo siguiente, se observa como los objetos "5" y "6" tienen siempre el mismo identificador.

>>> id(5)
505911024
>>> id(6)
505911040
>>> id(5)
505911024
>>> id(6)
505911040

Pero normalmente, los objetos se crean y se destruyen a medida que se usan y dejan de usar. En los ejemplos siguiente, se observa como los objetos (números grandes o cadenas) tienen cada vez un identificador distinto:

>>> id(12345)
50573840
>>> id(12346)
50576480
>>> id(12345)
50573856
>>> id(12346)
50573536
>>> id("hola")
50654720
>>> id("adios")
50654752
>>> id("hola")
50654656
>>> id("adios")
50654688

Si una variable hace referencia a un objeto, el objeto ya no destruye. En el ejemplo siguiente, se observa como el objeto "hola" mantiene el mismo identificador debido a que la variable "a" hace referencia a él.

>>> a = "hola"
>>> id("hola")
50651296
>>> id("adios")
50654656
>>> id("hola")
50651296
>>> id("adios")
50654720
>>> id("hola")
50651296

Variables

En Python, las variables son simples referencias a los objetos. Una variable es una especie de etiqueta o de alias para referirnos al objeto.

En Python las variables también tienen identificador, tipo y valor, pero esas tres características son las del objeto al que hace referencia.


Cuando asignamos un valor a una variable, lo que estamos creando es una etiqueta para referirnos al objeto que contiene el dato.

Por ejemplo, si a una variable se le asigna el número 5, Python crea el objeto número 5 y la variable hace referencia a ese objeto, como se comprueba en el ejemplo siguiente:

>>> id(5)  # Este es el identificador del objeto número entero "5"
505894368
>>> a = 5
>>> id(a)  # El identificador de la variable a es el mismo que el del número entero "5"
505894368

Python crea el objeto "número 5" cuando ve que en el programa se va a utilizar un 5. En el ejemplo anterior se crearía el objeto y después se ejecutaría la función id () que obtiene el identificador del objeto. Si la primera instrucción hubiera sido la asignación de la variable, de la misma forma se hubiera creado primero el objeto "número 5" y después se le hubiera asociado la etiqueta "a" a dicho objeto.

Lógicamente, el tipo de una variable coincide con el tipo del objeto al que hace referencia la variable, como se comprueba en el ejemplo siguiente:

>>> type(5)  # El tipo del objeto número entero "5" es int
<class 'int'>
>>> a = 5
>>> type(a)  # El tipo de la variable a el mismo que el del objeto número entero "5" 
<class 'int'>

Cuando cambiamos el valor de una variable, en la mayoría de los casos la variable pasa simplemente de hacer referencia a un objeto a hacer referencia a otro (aunque en algunos casos se puede estar modificando el valor del objeto, como se verá más adelante en esta lección), como se comprueba en el ejemplo siguiente:

>>> id(1)
505894304   # Este es el identificador del objeto "1"
>>> id(2)
505894320   # Este es el identificador del objeto "2"
>>> a = 1   # Si la variable "a" se asigna al objeto "1" ...
>>> id(a)   # ... la variable "a" tiene el mismo identificador que el objeto "1"
505894304
>>> a = 2   # Pero si la variable "a" se asigna al objeto "2" ...
>>> id(a)   # ... la variable "a" tiene el mismo identificador que el objeto "2"
505894320
>>> b = a   # Si la variable "b" se asigna al mismo objeto que la variable "a" ...
>>> id(b)   # ... la variable "b" tiene el mismo identificador que el objeto "2"
505894320

Variables, objetos mutables y objetos inmutables

En Python algunos tipos de objetos son inmutables, pero otros objetos son mutables:

Variables y objetos inmutables

Como los objetos inmutables no se pueden modificar, al modificar las variables que hacen referencia a objetos inmutables, las variables pasan siempre a hacer referencia a otros objetos.

Variables y objetos mutables

Sin embargo, en el caso de los objetos mutables tenemos dos posibilidades: modificar las variables o modificar los objetos mutables a los que hacen referencia. Por ejemplo, en el caso de las listas:

  1. En algunos casos las variables pasan a hacer referencia a otros objetos, como ocurría con los objetos inmutables.
    >>> a = [5]           # La variable "a" se asigna al objeto "lista [5]" y ...
    >>> b = a             # ... la variable "b" se asigna al mismo objeto que "a" ...
    >>> id(a), id(b)      # ... por eso "a" y "b" tienen el mismo identificador
    (45345888, 45345888)  
    >>> b = b + [6]       # Pero si añadimos un elemento a "b" ...
    >>> id(a), id(b)      # ... la variable "b" hace ahora referencia al objeto "[5, 6]" ...
    (45345888, 45346248)
    >>> a, b              # ... y por eso "a" y "b" son distintos.
    ([5], [5, 6])
    

    En este ejemplo, cuando modificamos el valor de la variable b ...

    >>> b = b + [6]       # Pero si añadimos un elemento a "b" ...

    ... en realidad Python no añade un elemento a "b" sino que:

    • evalúa la expresión de la derecha de la igualdad, es decir, añade el elemento "6" a una lista [5], obteniendo la lista [5, 6]
    • crea el objeto [5, 6]
    • asigna la variable "b" al objeto [5, 6]
  2. En otros casos sí que se modifican los objetos los objetos mutables a los que hacen referencia las variables:
    >>> a = [5]          # La variable "a" identifica a la lista [5] ...
    >>> b = a            # ... la variable "b" identifica al mismo valor que a...
    >>> id(a), id(b)     # ... por eso "a" y "b" tienen el mismo identificador
    (46531608, 46531608)
    >>> b += [6]         # Pero si añadimos un elemento a b usando += ...
    >>> id(a), id(b)     # ... tanto "a" como "b" siguen haciendo referencia a la misma lista ...
    (46531608, 46531608)
    >>> a, b             # ... que ha cambiado con respecto a su valor inicial
    ([5, 6], [5, 6])
    

    En este ejemplo, cuando modificamos el valor de la variable b ...

    >>> b += [6]       # Pero si añadimos un elemento a b usando += ...

    ... en realidad Python:

    • sí que añade el elemento "6" al objeto lista [5], convirtiéndola en la lista [5, 6]
    • tanto "a" como "b" siguen haciendo referencia a la misma lista, que ahora es [5, 6]

    Lo mismo pasaría si se utilizara el método append():

    >>> a = [5]          # La variable "a" identifica a la lista [5] ...
    >>> b = a            # ... la variable "b" identifica al mismo valor que a...
    >>> id(a), id(b)     # ... por eso "a" y "b" tienen el mismo identificador
    (46531608, 46531608)
    >>> b.append(6)      # Pero si añadimos un elemento a b usando append() ...
    >>> id(a), id(b)     # ... tanto "a" como "b" siguen haciendo referencia a la misma lista ...
    (46531608, 46531608)
    >>> a, b             # ... que ha cambiado con respecto a su valor inicial
    ([5, 6], [5, 6])
    

Más sobre creación y destrucción de objetos