¿Por qué Python tiene copia profunda y copia superficial?
1. Asignación
En Python FAQ1, la asignación se ha dejado muy clara. La clave es comprender la relación entre variables y objetos.
12345
gt gt gta = [1, 2, 3]> gt gtb = a gt gt gt print(id(a), id(b), sep = ' \ n ')139701469405552139701469405552
En Python, asignar el valor de una variable a otra variable en realidad agrega una "etiqueta" al objeto actualmente en la memoria.
De manera similar al ejemplo anterior, al usar la función incorporada id(), puedes ver que A y B apuntan al mismo objeto en la memoria. Si a es b, devolverá Verdadero.
2. Copia superficial (copia superficial)
Nota: La diferencia entre copia superficial y copia profunda es solo el objeto combinado. El llamado objeto compuesto es un objeto que contiene otros objetos, como listas e instancias de clases. Para números, cadenas y otros tipos "atómicos", no hay copias, todas las referencias son al objeto original.
La llamada "copia superficial" se refiere a la creación de un nuevo objeto cuyo contenido es una referencia a los elementos del objeto original. (Copia el objeto combinado, no el subobjeto)
Las copias superficiales comunes incluyen: operaciones de corte, funciones de fábrica, métodos copy() de objetos y funciones de copia en módulos de copia.
12345678910
gt gt gta = [1, 2, 3]> gt gtb = lista(a)> gt gtPrint(id(a), id(b)) # a y B tienen identidades diferentes 140601785066200 140601784764968 > gt; gt for x, y in zip(a, b): # Pero contienen la misma identidad de subobjeto...print(id(x), id(y)).. .140601911441984 140601911441984140601911442016 1406 01911442016140601911442048 140601911442048
Se puede ver claramente en lo anterior que la copia superficial obtiene B, A y B apuntan a listas diferentes en objetos de memoria, pero sus elementos apuntan al mismo objeto int. ¡Esto es una copia superficial!
Tercero, copia profunda (copia profunda)
La llamada "copia profunda" se refiere a crear un nuevo objeto y luego copiar recursivamente los subobjetos contenidos en el objeto original. El objeto profundamente copiado no tiene nada que ver con el objeto original.
Solo existe un método para la copia profunda: la función de copia profunda en el módulo de copia.
1234567891011
gt gt gt import copy gt gt gta = [1, 2, 3]> gt gtb = copy.deepcopy(a)> gt gt print(DNI(a ) ), cédula de identidad (b)) 140601785066200 gt; gt gt Para x, y en zip (a, b):... print (id (x), id (y))... 140601911441984 140601911441984140601911442016 140 6 01911442016 140601911442048 140601911442048
Después de leer el ejemplo anterior, algunas personas pueden preguntarse:
¿Por qué el ID del elemento en A y B sigue siendo el mismo cuando se utiliza la copia profunda?
Respuesta: Esto se debe a que para objetos inmutables, cuando se requiere un nuevo objeto, Python puede devolver una referencia a un objeto existente que tiene el mismo tipo y valor. Y este mecanismo no afectará la independencia mutua de A y B, porque cuando dos elementos apuntan al mismo objeto inmutable, asignar un valor a uno no afectará al otro.
Podemos usar una lista de objetos mutables para mostrar exactamente la diferencia entre una "copia superficial" y una "copia profunda":
1234567891011121314151617181920
gt gt gt importar copia gt gt gta = [[1, 2], [5, 6], [8, 9]] gt; gt gtB = copy.copy(a) #La copia superficial obtiene b>; (a) # La copia profunda obtiene C >; gt gt impresora (id (a), id (b)) # a y B son diferentes 139832578518984139832578335520 >; los objetos de a y b son iguales...print(id(x), id(y))...139832578622816 1398325786228139832578622672 1398325786267213983257862672139832578323104 65438 gt gtPrint (id (a), id(c)) # a es diferente de C 13983257851898413983257862456 > gt; gt para x, y en zip (a, c): # Los hijos de a y c también son diferentes... print(id(x), id(y))...139832578621520139832578622672 139832578518912139832578623104 13 9832578623392 p>
En este ejemplo, podemos ver claramente la diferencia entre copia superficial y copia profunda.
Resumen:
1. Tarea: simplemente copie la referencia del objeto, el id de los dos objetos es el mismo.
2. Copia superficial: crea un nuevo objeto combinado. Este nuevo objeto * * * comparte subobjetos en la memoria con el objeto original.
3. Copia profunda: cree un nuevo objeto compuesto y copie todos los subobjetos de forma recursiva. El nuevo objeto compuesto no tiene nada que ver con el objeto original. Aunque en realidad tendrás subobjetos inmutables, esto no afecta su independencia entre sí.
La única diferencia entre copia superficial y copia profunda es el objeto combinado. El llamado objeto compuesto es un objeto que contiene otros objetos, como listas e instancias de clases.
Para números, cadenas y otros tipos "atómicos", no hay copias, todas las referencias son al objeto original.