Документация Python неофициальный перевод

8.10. copy – Операции поверхностного и глубокого копированияcopy – Shallow and deep copy operations

Операторы присваивания в Python не копируют объекты, они создают привязки между целью и объектом. Для изменяемых коллекций или коллекций, содержащих изменяемые элементы, иногда требуется копия, чтобы можно было изменить одну копию, не меняя другую. Этот модуль предоставляет общие операции поверхностного и глубокого копирования (объяснены ниже).

Краткое описание интерфейса:

copy.copy(x)

Возвращает поверхностную копию x.

copy.deepcopy(x)

Возвращает глубокую копию x.

exception copy.error

Возбуждается при ошибках, специфичных для модуля.

Разница между поверхностным и глубоким копированием актуальна только для составных объектов (объектов, содержащих другие объекты, например, списки или экземпляры классов):

  • Поверхностная копия создаёт новый составной объект, а затем (насколько это возможно) вставляет в него ссылки на объекты, найденные в оригинале.
  • Глубокая копия создаёт новый составной объект, а затем рекурсивно вставляет в него копии объектов из оригинала.

Две проблемы, часто возникающие при глубоком копировании, которых нет при поверхностном:

  • Рекурсивные объекты (составные объекты, прямо или косвенно содержащие ссылку на себя) могут вызвать рекурсивный цикл.
  • Поскольку глубокое копирование копирует всё, оно может скопировать слишком много, например, административные структуры данных, которые должны быть общими даже между копиями.

Функция deepcopy() решает эти проблемы следующим образом:

  • хранение словаря “memo”, содержащего объекты, уже скопированные в текущем проходе копирования; и
  • предоставления пользовательским классам возможности переопределить операцию копирования или набор копируемых компонентов.

Этот модуль не копирует такие типы, как модуль, метод, трассировка стека, кадр стека, файл, сокет, окно, массив и любые подобные типы. Он «копирует» функции и классы (поверхностно и глубоко), возвращая исходный объект без изменений; это совместимо с тем, как эти типы обрабатываются модулем pickle.

Поверхностные копии словарей можно создать с помощью dict.copy(), а копии списков – присваиванием среза всего списка, например, copied_list = original_list[:].

Классы могут использовать те же интерфейсы для управления копированием, которые они используют для управления пиклингом. См. описание модуля pickle для информации об этих методах. В действительности модуль copy использует зарегистрированные функции pickle из модуля copyreg.

Чтобы класс мог определить собственную реализацию копирования, он может определить специальные методы __copy__() и __deepcopy__(). Первый вызывается для выполнения операции поверхностного копирования; дополнительные аргументы не передаются. Второй вызывается для выполнения операции глубокого копирования; ему передаётся один аргумент – словарь memo. Если реализация __deepcopy__() требует сделать глубокую копию компонента, она должна вызвать функцию deepcopy() с компонентом в качестве первого аргумента и словарём memo в качестве второго аргумента.

См. также

Модуль pickle
Обсуждение специальных методов, используемых для поддержки извлечения и восстановления состояния объекта.