La forma en la que Python maneja los objetos (evito el nombre variables, ya verás por qué) es un tanto diferente a lo que generalmente se está acostumbrado por otros lenguajes, y puede prestar a la confusión para quienes lo ignoren. Este artículo es una traducción con algunas ligeras modificaciones de una sección del texto Code Like a Pythonista: Idiomatic Python y se encuentra bajo los términos de la licencia Creative Commons Attribution/Share-Alike (BY-SA).
En muchos otros lenguajes, como C o Visual Basic, por poner algunos ejemplos, asignar a una variable es similar a poner un valor en una caja.
int a = 1;
La caja a
ahora contiene el número entero 1.
Asignar otro valor a la misma variable reemplaza el contenido de la caja:
a = 2;
Ahora la caja a
contiene el entero 2. Entonces, el código anterior se leería «poner el valor 2 en el contenedor a
«.
Asignar una variable a otra hace una copia del valor que contiene la primera y lo pone en la nueva caja.
int b = a;
b
es una segunda caja, con una copia del número 2. La caja a
tiene una copia separada. Por ende la expresión indicaría «poner el valor que contiene a
en b
, sin alterar a
.»
a
no es b
; son dos contenedores diferentes simplemente con el mismo número.
Python, en cambio, tiene «nombres». Un «nombre» o «identificador» es como una etiqueta atada a un objeto (en este caso un número entero).
a = 1
Aquí, el número entero 1 (que, como todas las cosas en Python, es un objeto) tiene una etiqueta llamada a
.
Si reasignamos al identificador a
, simplemente movemos la etiqueta a otro objeto.
a = 2
Ahora el nombre a
está atado al objeto 2 (que también es un número entero).
El objeto original (el número 1) ya no tiene la etiqueta a
. Puede que todavía exista, pero no podemos acceder a él a través de esta etiqueta. (Cuando un objeto no tiene más referencias o etiquetas, es eliminado).
Si asignamos un nombre (o identificador) a otro, solo estamos atanado otra etiqueta a un objeto existente.
b = a
El nombre b
es simplemente una segunda etiqueta atada al mismo objeto que a
.
Si bien comunmente nos referimos a «variables» incluso en Python (porque es una terminología convencional), en realidad queremos decir «nombres» o «identificadores». En Python, las «variables» no son cajas que contienen valores sino etiquetas asociadas a un valor (objeto) determinado.
Antes de finalizar, veamos un ejemplo. El operador is
en Python permite determinar si dos nombres o identificadores hacen referencia al mismo objeto.
>>> a = [] >>> b = a >>> a is b True
En esta secuencia tenemos dos identificadores (a
y b
) pero solo un objeto (la lista). Por ende, podemos utilizarlos indistintamente para añadir elementos a la lista.
>>> a.append(1) >>> b.append(2) >>> a [1, 2] >>> b [1, 2]
Observemos ahora el contraejemplo.
>>> a = [] >>> b = [] >>> a is b False
Aquí hay dos identificadores y dos objetos. a
y b
contienen dos listas diferentes, aunque equivalentes.
>>> a == b True
En tanto alguna de ellas no sea modificada…
>>> b.append(1) >>> a == b False
Un error en el que incurren muchos programadores de Python es al momento de asignar objetos mutables (como una lista) como argumentos por defecto.
def mala_funcion(nuevo_item, una_lista=[]): una_lista.append(nuevo_item) return una_lista
El problema aquí es que el valor por defecto de una_lista
, una lista vacía, es evaluado en el momento en el que se define la función. Entonces, cada vez que llamas a la función, obtienes el mismo valor por defecto. Pruébalo varias veces:
>>> print(mala_funcion("uno")) ['uno'] >>> print(mala_funcion("dos")) ['uno', 'dos']
Las listas son objetos mutables; puedes cambiar su contenido. La forma correcta de obtener una lista por defecto (o un diccionaro, o un set
) es crearla durante la ejecución, dentro de la función:
def buena_funcion(nuevo_item, una_lista=None): if una_lista is None: una_lista = [] una_lista.append(nuevo_item) return una_lista
Ahora el resultado es el esperado:
>>> print(buena_funcion("uno")) ['uno'] >>> print(buena_funcion("dos")) ['dos']
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter
en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.