ProgrammazioneSviluppatore Python

Descrivi la differenza tra shallow copy e deep copy in Python. Come copiare correttamente le strutture dati annidate? Come funziona il modulo copy?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

In Python, la copia degli oggetti può essere superficiale (shallow copy) e profonda (deep copy). La copia superficiale crea un nuovo contenitore, ma gli oggetti annidati non vengono copiati, ma si utilizzano riferimenti agli stessi oggetti. La copia profonda crea ricorsivamente nuove copie di tutti gli oggetti annidati, garantendo l'indipendenza della copia.

Il modulo copy fornisce i metodi copy() (shallow copy) e 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]] ← l'oggetto originale è cambiato! deep[1][1] = 42 print(original) # [[99, 2], [3, 4]] - non è cambiato

Domanda trabocchetto.

Qual è la differenza tra l'operatore list2 = list1 e l'applicazione di copy.copy(list1)?

Risposta: L'operatore list2 = list1 crea un nuovo riferimento allo stesso oggetto. copy.copy(list1) fa una copia superficiale, creando un nuovo oggetto lista ma con gli stessi oggetti interni. Per le strutture annidate, la copia superficiale non è sufficiente: è necessaria una deep copy.

Esempi di errori reali a causa della mancanza di conoscenza delle sottigliezze dell'argomento.


Storia

Durante lo sviluppo di un'API REST, i dati dal modello venivano copiati con un'assegnazione normale (data = template). La richiesta successiva modificava accidentalmente il "modello" per tutti gli utenti successivi, poiché veniva utilizzato lo stesso riferimento.


Storia

Nel modulo di reporting, i dati venivano copiati tramite copy.copy(), anche se la struttura era annidata (liste in dizionari). Le modifiche nella copia si riflettevano inaspettatamente nei dati originali, causando errori nella statistica.


Storia

In un progetto bancario, una copia errata di un oggetto complesso annidato tramite copy.copy() (e non deepcopy()) ha portato alla perdita della storia delle transazioni: le nuove operazioni sovrascrivevano le vecchie, poiché gli elementi annidati erano condivisi.