В Python копирование объектов может быть поверхностным (shallow copy) и глубоким (deep copy). Поверхностная копия создаёт новый контейнер, но вложенные объекты при этом не копируются, а используются ссылки на те же самые объекты. Глубокая копия рекурсивно создаёт новые копии всех вложенных объектов, обеспечивая независимость копии.
Модуль copy предоставляет методы copy() (shallow copy) и 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]] ← изменился исходный объект! deep[1][1] = 42 print(original) # [[99, 2], [3, 4]] - не изменился
Чем отличается оператор
list2 = list1от применения copy.copy(list1)?
Ответ: Оператор list2 = list1 создаёт новую ссылку на тот же объект. copy.copy(list1) делает поверхностную копию, создавая новый объект-список, но с теми же внутренними объектами. Для вложенных структур поверхностного копирования недостаточно — нужна deep copy.
История
При разработке REST API данные из шаблона копировались обычным присваиванием (
data = template). Следующий запрос случайно модифицировал "шаблон" для всех последующих пользователей, потому что использовалась одна и та же ссылка.
История
В отчётном модуле данные копировались через
copy.copy(), хотя структура была вложенной (списки в словарях). Модификации в копии неожиданно отражались в исходных данных, вызывая ошибки в статистике.
История
В одном банковском проекте некорректная копия сложного вложенного объекта через
copy.copy()(а неdeepcopy()) привела к потере истории транзакций — новые операции перезаписывали старые, поскольку вложенные элементы были общими.