Kopia płytka (shallow copy) tworzy nowy obiekt na najwyższym poziomie, ale zagnieżdżone obiekty (elementy list, zagnieżdżone słowniki itd.) dzielą pamięć z oryginałem. Kopia głęboka (deep copy) rekurencyjnie kopiuje wszystkie poziomy obiektów.
Można używać przez moduł copy:
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) deep = copy.deepcopy(original) shallow[0][0] = 99 # Zmienia i original, i shallow print(original) # [[99, 2], [3, 4]] # Teraz z deep original = [[1, 2], [3, 4]] deep = copy.deepcopy(original) deep[0][0] = 99 print(original) # [[1, 2], [3, 4]]
copy.copy(obj): kopiuje tylko "opakowanie"copy.deepcopy(obj): pełna rekurencyjna kopiaCo się stanie podczas kopiowania krotki, która zawiera obiekty zmienne?
tuple jest niezmienny, ale jego elementy mogą być zmienne (np. lista). Shallow copy i deep copy różnią się:
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]) # Przy deep copy: t = ([1, 2], [3, 4]) deep = copy.deepcopy(t) deep[0][0] = 88 print(t) # ([1, 2], [3, 4])
Historia
W aplikacji do przetwarzania dokumentów dane przechowywano na liście wewnątrz słownika. Podczas kopiowania obiektów za pomocą copy.copy zagnieżdżone elementy przypadkowo zmieniały się podczas modyfikacji nowego obiektu. W rezultacie zmieniły się dane źródłowe w innych częściach systemu! Wystąpiła korupcja danych. Poprawiono to tylko poprzez zamianę na deepcopy.
Historia
W projekcie związanym z uczeniem maszynowym podczas zapisywania hiperparametrów modeli kopiowano listę konfiguracji przez standardowe przypisanie i shallow copy, po czym różne eksperymenty wzajemnie zmieniały swoje parametry. Źródło błędu znaleziono po diagnozowaniu zachowania kopiowania zagnieżdżonych list przez deepcopy.
Historia
W oprogramowaniu finansowym deep copy przypadkowo zastosowano do obiektu, który zawiera otwarty plik (handle), co spowodowało TypeError: cannot pickle '_io.TextIOWrapper' object — ponieważ copy.deepcopy używa pod maską pickle. Poprawiono to przez wyraźne przetwarzanie takich pól lub poprzez wywołanie shallow copy.