programowanieProgramista Python

Opisz różnicę między shallow copy a deep copy w Pythonie. Jak prawidłowo kopiować złożone struktury danych? Jak działa moduł copy?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

W Pythonie kopiowanie obiektów może być płytkie (shallow copy) i głębokie (deep copy). Płytka kopia tworzy nowy kontener, ale zagnieżdżone obiekty nie są kopiowane, a używane są odnośniki do tych samych obiektów. Głęboka kopia rekurencyjnie tworzy nowe kopie wszystkich zagnieżdżonych obiektów, zapewniając niezależność kopii.

Moduł copy udostępnia metody copy() (shallow copy) i deepcopy() (deep copy):

import copy oryginalny = [[1, 2], [3, 4]] płytki = copy.copy(oryginalny) głęboki = copy.deepcopy(oryginalny) płytki[0][0] = 99 print(oryginalny) # [[99, 2], [3, 4]] ← zmieniony oryginalny obiekt! głęboki[1][1] = 42 print(oryginalny) # [[99, 2], [3, 4]] - nie zmienił się

Pytanie z haczykiem.

Czym różni się operator list2 = list1 od użycia copy.copy(list1)?

Odpowiedź: Operator list2 = list1 tworzy nowy odnośnik do tego samego obiektu. copy.copy(list1) wykonuje płytką kopię, tworząc nowy obiekt-listę, ale z tymi samymi wewnętrznymi obiektami. Dla złożonych struktur płytkie kopiowanie jest niewystarczające — potrzebna jest głęboka kopia.

Przykłady realnych błędów z powodu niewiedzy o szczegółach tematu.


Historia

Podczas opracowywania REST API dane z szablonu były kopiowane zwykłym przypisaniem (data = template). Następne zapytanie przypadkowo zmodyfikowało "szablon" dla wszystkich kolejnych użytkowników, ponieważ użyto tego samego odnośnika.


Historia

W module raportowym dane kopiowano przez copy.copy(), chociaż struktura była zagnieżdżona (listy w słownikach). Modyfikacje w kopii niespodziewanie wpływały na dane oryginalne, powodując błędy w statystyce.


Historia

W jednym z projektów bankowych niepoprawna kopia złożonego zagnieżdżonego obiektu przez copy.copy() (a nie deepcopy()) doprowadziła do utraty historii transakcji — nowe operacje nadpisywały stare, ponieważ zagnieżdżone elementy były wspólne.