копирование — операции копирования поверхностного и глубокого копирования
Исходный код: Lib/copy.py
Операторы присваивания в Python не копируют объекты, они создают связи между целевым объектом и объектом. Для коллекций, которые являются изменяемыми или содержат изменяемые элементы, иногда требуется копия, чтобы можно было изменить одну копию без изменения другой. Этот модуль предоставляет универсальные операции поверхностного и глубокого копирования (объяснение ниже).
Резюме интерфейса:
-
copy.copy(obj) -
Возвращает поверхностную копию obj.
-
copy.deepcopy(obj[, memo]) -
Возвращает глубокую копию obj.
-
copy.replace(obj, /, **changes) -
Создает новый объект того же типа, что и obj, заменяя поля значениями из changes.
Добавлен в версии 3.13.
-
exception copy.Error -
Выбрасывается для ошибок, специфичных для модуля.
Разница между поверхностным и глубоким копированием актуальна только для составных объектов (объектов, содержащих другие объекты, таких как списки или экземпляры классов):
- Поверхностная копия создаёт новый составной объект и затем (в максимально возможной степени) вставляет ссылки в него на объекты, найденные в оригинале.
- Глубокая копия создаёт новый составной объект и затем рекурсивно вставляет в него копии объектов, найденных в оригинале.
Часто существуют две проблемы с операциями глубокого копирования, которых нет при операциях поверхностного копирования:
- Рекурсивные объекты (составные объекты, которые прямо или косвенно содержат ссылку на себя) могут вызвать рекурсивный цикл.
- Поскольку глубокое копирование копирует всё, оно может копировать слишком много, например, данные, которые предназначены для совместного использования между копиями.
Функция deepcopy() избегает этих проблем, используя:
- поддержание словаря
memoобъектов, уже скопированных во время текущего прохода копирования; и - разрешение классам пользовательского определения переопределить операцию копирования или набор копируемых компонентов.
Этот модуль не копирует типы, такие как модуль, метод, трассировка стека, кадр стека, файл, сокет, окно или любые аналогичные типы. Он «копирует» функции и классы (поверхностно и глубоко), возвращая исходный объект без изменений; это совместимо с тем, как они обрабатываются модулем pickle.
Поверхностные копии словарей можно создать, используя dict.copy(), а списков — присваивая срез всего списка, например, copied_list = original_list[:].
Классы могут использовать те же интерфейсы для управления копированием, что и для управления сериализацией. См. описание модуля pickle для получения информации об этих методах. Фактически, модуль copy использует зарегистрированные функции сериализации из модуля copyreg.
Для того, чтобы класс определил свою собственную реализацию копирования, он может определить специальные методы __copy__() и __deepcopy__().
-
object.__copy__(self) -
Вызывается для реализации операции поверхностного копирования; дополнительные аргументы не передаются.
-
object.__deepcopy__(self, memo) -
Вызывается для реализации операции глубокого копирования; ему передаётся один аргумент — словарь memo. Если реализация
__deepcopy__нуждается в создании глубокой копии компонента, она должна вызвать функциюdeepcopy()с компонентом в качестве первого аргумента и словарем memo в качестве второго аргумента. Словарь memo следует рассматривать как непрозрачный объект.
Функция copy.replace() более ограничена, чем copy() и deepcopy(), и поддерживает только именованные кортежи, созданные с помощью namedtuple(), dataclasses и других классов, которые определяют метод __replace__().
-
object.__replace__(self, /, **changes) -
Этот метод должен создать новый объект того же типа, заменив поля значениями из changes.
См. также
-
Modulepickle -
Обсуждение специальных методов, используемых для поддержки извлечения и восстановления состояния объекта.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/copy.html