Присваивание переменной (например, a = b) в Python не копирует сам объект, а лишь создает новое имя (ссылку) на существующий объект. Изменения по одному имени будут видны и по другому, если это изменяемый объект.
Shallow copy (поверхностное копирование), например через copy.copy(obj) или срез [:] для списка, создает новый объект верхнего уровня, но вложенные объекты внутри копируются по ссылке (т.е. обе структуры "смотрят" на одни и те же подконтейнеры). Если изменять вложенные объекты, изменения будут видны через оба объекта.
Пример:
import copy lst1 = [[1,2], [3,4]] lst2 = copy.copy(lst1) # или lst1[:] lst1[0][0] = 100 print(lst2) # [[100, 2], [3, 4]]
lst2 — новый список, но его первый элемент — тот же вложенный список.
Вопрос: Чем отличается lst2 = lst1[:] и lst2 = copy.copy(lst1)?
Ответ: На практике для обычных (одноуровневых) списков нет отличий — оба способа делают поверхностную копию списка. Однако, для пользовательских контейнерных классов может быть разное поведение (например, если реализован свой метод __copy__). Точно так же для других типов (dict, set и др.) использовать специализированный модуль copy безопаснее.
import copy lst1 = [1, 2, 3] lst2 = lst1[:] lst3 = copy.copy(lst1) print(lst2 == lst3) # True
История
В проекте с обработкой конфигов разработчик дублировал дефолтные параметры через присваивание params = default_params и рассчитывал "изолированно" их менять. В итоге любые изменения в любой копии вели к каскаду изменений во всех частях приложения, потому что на деле работали с одним объектом.
История
Неопытный программист использовал поверхностную копию списка для хранения состояния игры (game_states = states[:]). При вложенной структуре (списки фигур на поле) изменения внутри одного состояния "протекали" в другие, ломая историю откатов и повторов ходов.
История
При попытке клонирования данных в ООП-приложении выбор был между срезом и copy.copy(). Но в структуре встретился свой класс со своим методом copy, который был учтен только при использовании copy.copy(). Срез проигнорировал логику копирования объекта, и возникли неочевидные баги.