copy — Операции мелкого и глубокого копирования

Исходный код: Lib/copy.py.


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

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

copy.copy(x)

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

copy.deepcopy(x[, memo])

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

exception copy.Error

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

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

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

  • При глубоком копировании создается новый составной объект, а затем, рекурсивно, в него вставляются копии объектов, имеющихся в оригинале.

При выполнении операций глубокого копирования часто возникают две проблемы, которых нет при выполнении операций поверхностного копирования:

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

  • Поскольку глубокое копирование копирует все, оно может скопировать слишком много, например, данные, которые предназначены для совместного использования между копиями.

Функция deepcopy() позволяет избежать этих проблем:

  • сохранение словаря memo объектов, уже скопированных во время текущего прохода копирования; и

  • позволяя пользовательским классам переопределять операцию копирования или набор копируемых компонентов.

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

Неглубокие копии словарей можно сделать с помощью dict.copy(), а списков - назначив фрагмент всего списка, например, copied_list = original_list[:].

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

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

См.также

Модуль pickle

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

Вернуться на верх