En Python, la copia de objetos puede ser superficial (shallow copy) y profunda (deep copy). Una copia superficial crea un nuevo contenedor, pero los objetos anidados no se copian, sino que se utilizan las referencias a los mismos objetos. Una copia profunda crea recursivamente nuevas copias de todos los objetos anidados, asegurando la independencia de la copia.
El módulo copy proporciona los métodos copy() (shallow copy) y deepcopy() (deep copy):
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 print(original) # [[99, 2], [3, 4]] ← ¡se modificó el objeto original! deep[1][1] = 42 print(original) # [[99, 2], [3, 4]] - no se modificó
¿En qué se diferencia el operador
list2 = list1del uso de copy.copy(list1)?
Respuesta: El operador list2 = list1 crea una nueva referencia al mismo objeto. copy.copy(list1) hace una copia superficial, creando un nuevo objeto lista, pero con los mismos objetos internos. Para estructuras anidadas, la copia superficial no es suficiente: se necesita una deep copy.
Historia
Al desarrollar una API REST, los datos del template se copiaban mediante asignación simple (
data = template). La siguiente solicitud modificó accidentalmente el "template" para todos los usuarios subsecuentes, ya que se utilizaba la misma referencia.
Historia
En el módulo de informes, los datos se copiaban a través de
copy.copy(), aunque la estructura era anidada (listas en diccionarios). Las modificaciones en la copia se reflejaban inesperadamente en los datos originales, causando errores en las estadísticas.
Historia
En un proyecto bancario, una copia incorrecta de un objeto anidado complejo a través de
copy.copy()(en lugar dedeepcopy()) llevó a la pérdida del historial de transacciones — nuevas operaciones sobrescribían las antiguas, ya que los elementos anidados eran compartidos.