Esto es muy simple una vez que entiendes el concepto de
inmutabilidad.
Definición:
Cita:
Iniciado por Wikipedia un «objeto inmutable» es un objeto cuyo estado no puede ser modificado una vez creado.
Algunos puntos a tener en cuenta:
1. En python todo es un objeto.
2. En python puedes clasificar cualquier objeto como inmutable o mutable.
Ejemplos de objetos mutables:
Listas, Diccionarios, Sets
Ejemplos de objetos inmutables:
Enteros, Flotantes, Cadenas, Tuplas, Frozensets
Mas ejemplos de inmutabilidad.
Código Python:
Ver originalmy_str = " ola mundo"
my_str[0] = "H"
# TypeError: 'str' object does not support item assignment
Como puedes ver, esto arrojara una excepción de tipo TypeError. Por que como dije arriba las cadenas son inmutables.
Código Python:
Ver originalmy_list = [0, 2, 3]
my_list[0] = 1
Y aquí no hay ningún error. Y funciona porque nuestro objeto es mutable. Y como puedes ver, paso de tener [0, 2, 3] a tener [1, 2, 3].
¿Bueno y que tiene que ver esto con deep copy o swallow copy?
Primero vamos a ver que pasa, si no aplicamos una copia.
Código Python:
Ver originala = [1, 2, 3]
print a # [1, 2, 3]
b = a # Esto es una referencia a la lista a, no es una copia
del b[0]
print a # [2, 3] modifico nuestra lista a
print b # [2, 3]
¿Como puedo evitar esto si no existiera un método copy?
Fácil creas una copia manualmente.
Código Python:
Ver originaldef copy(some_list):
copy_list = []
for item in some_list:
copy_list.append(item)
return copy_list
a = [1, 2, 3]
b = copy(a)
del b[0]
print a # [1, 2, 3]
print b # [2, 3]
Como puedes ver es perfectamente y crea una copia. Pero esto es un swallow copy.
¿Pero que tal si tengo objetos inmutables anidados?
Código Python:
Ver originala = [[1, 2], [3, 4]]
b = copy(a)
del b[0]
print a # [[1, 2], [3, 4]]
print b # [[3, 4]]
# Funciona perfecto
del b[0][0]
print a # [[1, 2], [4]]
print b # [[4]]
# WTF!
Ok, ¿Que paso aquí?
Es bastante fácil, cuando creo una copia de la lista, asumo que todos los objetos de la lista son inmutables. Cosa que en la vida real no es así.
Para evitar esto, existe algo llamado deep copy. Que hará una copia, no importa los niveles de anidamiento que tengas.
Mas información al respecto, puedes leer la documentación.
https://docs.python.org/2/library/copy.html