Introducción
En este laboratorio, cubriremos los conceptos básicos de asignación y referencia en Python. Exploraremos cómo Python maneja las asignaciones, cómo crear referencias y cómo trabajar con objetos mutables e inmutables.
💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí
En este laboratorio, cubriremos los conceptos básicos de asignación y referencia en Python. Exploraremos cómo Python maneja las asignaciones, cómo crear referencias y cómo trabajar con objetos mutables e inmutables.
En Python, la asignación es el proceso de vincular un nombre a un objeto. Las declaraciones de asignación tienen la siguiente forma general:
variable = expression
La expresión en el lado derecho se evalúa y su valor se asigna a la variable en el lado izquierdo.
Veamos un ejemplo simple:
Abra la Terminal y escriba el siguiente comando en la terminal.
python3
Luego, escriba el siguiente código.
## Asigne el valor 42 a la variable 'x' e imprímala.
x = 42
print(x)
Salida:
42
Aquí, asignamos x
a la variable 42
usando el operador =
. Luego, imprimimos los valores de x
.
En Python, las variables son referencias a objetos. Cuando asignas un valor a una variable, estás en realidad creando una referencia al objeto que representa ese valor.
Aquí hay un ejemplo para ilustrar este concepto:
## Ilustra las referencias de Python.
x = [1, 2, 3]
y = x
y.append(4)
print("x:", x)
print("y:", y)
Salida:
x: [1, 2, 3, 4]
y: [1, 2, 3, 4]
En este ejemplo, tanto x
como y
se refieren al mismo objeto de lista. Cuando modificamos la lista a través de la referencia y
agregando 4
, el cambio se refleja tanto en x
como en y
.
Python tiene dos tipos de objetos: mutables e inmutables.
Los objetos mutables pueden ser modificados después de ser creados. Las listas, los diccionarios y los conjuntos son ejemplos de objetos mutables.
Los objetos inmutables no pueden ser modificados una vez que son creados. Los enteros, los flotantes, las cadenas y las tuplas son ejemplos de objetos inmutables.
Veamos un ejemplo que demuestra la diferencia entre objetos mutables e inmutables:
## Ejemplo de objeto mutable
mutable_list = [1, 2, 3]
another_mutable_list = mutable_list
another_mutable_list.append(4)
print("mutable_list:", mutable_list)
Salida:
mutable_list: [1, 2, 3, 4]
mutable_list
agrega un 4
al final de la lista porque es un objeto mutable, pero los objetos inmutables no pueden ser modificados una vez que son creados.
## Ejemplo de objeto inmutable
immutable_string = "hello"
another_immutable_string = immutable_string
another_immutable_string = another_immutable_string.upper()
print("immutable_string:", immutable_string)
Salida:
immutable_string: hello
No tiene ningún cambio, y si queremos cambiar la immutable_string
de la siguiente manera, la shell de Python lanzará un TypeError:
immutable_string[0] = '1'
Salida:
TypeError: 'str' object does not support item assignment
Veamos algunos más ejemplos para reforzar los conceptos que hemos aprendido:
Evite usar objetos mutables como argumentos predeterminados en funciones:
def bad_append(new_item, a_list=[]):
a_list.append(new_item)
return a_list
print(bad_append('one'))
Salida:
['one']
Parece correcto, pero si llamamos a esta función nuevamente:
print(bad_append('two'))
Salida:
['one', 'two']
El problema aquí es que el valor predeterminado de a_list
se evalúa en el momento de la definición de la función. Entonces, cada vez que llames a la función, obtienes el mismo valor predeterminado. La forma correcta es crearlo en tiempo de ejecución en su lugar, dentro de la función.
def append_to_list(item: int, a_list: list = None) -> list:
"""Agrega un elemento a una lista y devuelve la lista actualizada."""
if a_list is None:
a_list = []
a_list.append(item)
return a_list
list_a = append_to_list(1, [1, 2, 3])
print(list_a)
Salida:
[1, 2, 3, 1]
Utilice el módulo copy
para crear un nuevo objeto cuando desee trabajar con una copia de un objeto mutable:
import copy
## Demuestra el uso del módulo copy.
original_list = [1, 2, 3]
copied_list = copy.copy(original_list)
copied_list.append(4)
print("original_list:", original_list)
print("copied_list:", copied_list)
Salida:
original_list: [1, 2, 3]
copied_list: [1, 2, 3, 4]
En este ejemplo, copied_list
es un nuevo objeto que es una copia de original_list
. Cuando agregamos 4
a copied_list
, original_list
permanece sin cambios.
Para objetos mutables anidados, usar la función copy
no funciona:
## su ejemplo de copia aquí
original_nested_list = [[1, 2], [3, 4]]
copied_nested_list = copy.copy(original_nested_list)
copied_nested_list[0].append(5)
print("original_nested_list:", original_nested_list)
print("copied_nested_list:", copied_nested_list)
Salida:
original_nested_list: [[1, 2, 5], [3, 4]]
copied_nested_list: [[1, 2, 5], [3, 4]]
Podemos ver que cuando agregamos 5
a copied_nested_list
, original_nested_list
también agrega 5
. Entonces, debería usar la función deepcopy
en su lugar:
## su ejemplo de deepcopy aquí
original_nested_list = [[1, 2], [3, 4]]
deep_copied_list = copy.deepcopy(original_nested_list)
deep_copied_list[0].append(5)
print("original_nested_list:", original_nested_list)
print("deep_copied_list:", deep_copied_list)
Salida:
original_nested_list: [[1, 2], [3, 4]]
deep_copied_list: [[1, 2, 5], [3, 4]]
En este ejemplo, la función deepcopy
copia recursivamente original_nested_list
, mientras que la función copy
crea un objeto de referencia a los datos de primer nivel de original_nested_list
.
En este tutorial de programación en Python, cubrimos los conceptos básicos de asignación y referencia en Python. Exploramos cómo Python maneja las asignaciones, cómo crear referencias y cómo trabajar con objetos mutables e inmutables. Al comprender estos conceptos, estarás mejor preparado para escribir código Python eficiente y correcto.