Flache Kopie (shallow copy) erstellt ein neues Objekt der obersten Ebene, aber die verschachtelten Objekte (Elemente von Listen, verschachtelte Wörterbücher usw.) teilen sich den Speicher mit dem Original. Tiefe Kopie (deep copy) kopiert rekursiv alle Ebenen von Objekten.
Kann über das Modul copy verwendet werden:
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 # Ändert sowohl original als auch shallow print(original) # [[99, 2], [3, 4]] # Jetzt mit deep original = [[1, 2], [3, 4]] deep = copy.deepcopy(original) deep[0][0] = 99 print(original) # [[1, 2], [3, 4]]
copy.copy(obj): kopiert nur die "Umhüllung"copy.deepcopy(obj): vollständige rekursive KopieWas passiert bei der Kopierung eines Tuples, das veränderliche Objekte enthält?
tuple ist unveränderlich, aber seine Elemente können veränderlich sein (z. B. eine Liste). Shallow copy und deep copy unterscheiden sich:
import copy t = ([1, 2], [3, 4]) shallow = copy.copy(t) deep = copy.deepcopy(t) shallow[0][0] = 99 print(t) # ([99, 2], [3, 4]) # Bei deep copy: t = ([1, 2], [3, 4]) deep = copy.deepcopy(t) deep[0][0] = 88 print(t) # ([1, 2], [3, 4])
Geschichte
In einer Anwendung zur Dokumentenverarbeitung wurden die Daten in einer Liste innerhalb eines Wörterbuchs gespeichert. Beim Kopieren von Objekten mit copy.copy änderten sich die verschachtelten Elemente versehentlich bei der Modifizierung des neuen Objekts. Schließlich wurden die Originaldaten in anderen Teilen des Systems geändert! Es kam zu Datenkorruption. Das wurde nur durch den Austausch gegen deepcopy behoben.
Geschichte
In einem Projekt für maschinelles Lernen wurden beim Speichern von Hyperparametern der Modelle Listen von Konfigurationen durch Standardzuweisung und flache Kopie kopiert, wodurch verschiedene Experimente ihre Parameter gegenseitig änderten. Die Fehlerquelle wurde nach der Diagnose des Verhaltens beim Kopieren verschachtelter Listen über deepcopy gefunden.
Geschichte
In einer Finanzsoftware wurde deep copy versehentlich auf ein Objekt angewendet, das eine offene Datei (handle) enthält, was zu TypeError: cannot pickle '_io.TextIOWrapper' object führte - weil copy.deepcopy intern pickle verwendet. Das wurde durch explizite Behandlung solcher Felder oder durch Aufruf von shallow copy behoben.