Ответ
Разница заключается в том, как копируются вложенные (составные) объекты. Обе функции находятся в модуле copy.
copy.copy(x) (Поверхностное копирование):
- Создает новый составной объект (например, новый список или словарь).
- Затем вставляет ссылки на объекты, найденные в оригинале. Если элемент оригинала — это список, в копию попадет ссылка на тот же самый список, а не его копия.
- Изменения во вложенных изменяемых объектах оригинала отразятся на копии, и наоборот.
copy.deepcopy(x) (Глубокое копирование):
- Создает новый составной объект.
- Затем рекурсивно вставляет копии объектов, найденных в оригинале. Копируется весь объект «вглубь».
- Полностью независимая копия. Изменения в любой части оригинала или копии не затрагивают друг друга.
Практические примеры:
import copy
# Исходная структура с вложенным списком
original = [1, 2, [3, 4]]
# Поверхностное копирование
shallow_copied = copy.copy(original)
# Глубокое копирование
deep_copied = copy.deepcopy(original)
# Модифицируем вложенный список в оригинале
original[2].append(5)
print("Original:", original) # [1, 2, [3, 4, 5]]
print("Shallow copy:", shallow_copied) # [1, 2, [3, 4, 5]] -> изменился!
print("Deep copy:", deep_copied) # [1, 2, [3, 4]] -> остался неизменным
Когда что использовать:
copy.copy(): Когда объект состоит только из неизменяемых типов (числа, строки, кортежи) или когда вам намеренно нужны общие ссылки на вложенные изменяемые объекты (редкий случай).copy.deepcopy(): Когда вам нужна полная, независимая копия сложной структуры данных (списки списков, словари, содержащие другие словари, пользовательские объекты). Это безопасный, но более ресурсоемкий вариант.
Важно: deepcopy может корректно обрабатывать рекурсивные ссылки и пользовательские объекты, если они определяют методы __copy__() или __deepcopy__().