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() з компонентом як першим аргументом і словником memo як другим аргументом. Словник memo слід розглядати як непрозорий об’єкт.

Дивись також

Модуль pickle

Обговорення спеціальних методів, які використовуються для підтримки пошуку та відновлення стану об’єкта.