Пропустить до содержимого

Как использовать deep и shallow copy в Python?

[

Копирование объектов Python: понятие глубокой и поверхностной копии

Python предоставляет различные возможности для копирования объектов, чтобы можно было работать с ними независимо от оригинала. В данной статье мы рассмотрим, как создавать поверхностные и глубокие копии объектов в Python с помощью подробных примеров и объяснений.

Создание поверхностной копии

Pоверхностная копия означает создание нового объекта, содержащего ссылки на вложенные объекты, найденные в оригинале. При этом копирование не выполняется для дочерних объектов самих по себе. Давайте рассмотрим пример для более понятного объяснения:

xs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
ys = list(xs) # Создание поверхностной копии

В данном примере переменная ys будет новым и независимым объектом со всеми содержимым переменной xs. Вы можете проверить это, исследовав оба объекта:

print(xs) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(ys) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Теперь проведем эксперимент, чтобы подтвердить, что ys действительно независим от оригинала. Добавим новый вложенный список в переменную xs и проверим, не повлияло ли это на копию ys:

xs.append(['new sublist'])
print(xs) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], ['new sublist']]
print(ys) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Заметим, что изменение оригинального списка не повлияло на копию, потому что мы создали только поверхностную копию. Однако копия ys по-прежнему содержит ссылки на дочерние объекты оригинала.

Создание глубокой копии

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

import copy
xs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
ys = copy.deepcopy(xs) # Создание глубокой копии

Теперь переменная ys будет полностью независимым объектом с таким же содержимым, как и xs. Проверим это:

print(xs) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(ys) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Проведем тот же эксперимент, что и в предыдущем примере:

xs.append(['new sublist'])
print(xs) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], ['new sublist']]
print(ys) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

В этом случае изменение оригинального списка не повлияет на копию, потому что мы создали глубокую копию. Копия ys содержит полностью независимые объекты, которые были скопированы из оригинала.

Копирование произвольных объектов Python

Мы рассмотрели копирование встроенных коллекций Python, таких как списки, словари и множества. Однако поверхностное и глубокое копирование работает и для других объектов Python благодаря модулю copy. Вы можете создавать поверхностные и глубокие копии своих собственных объектов, реализовав методы __copy__() и __deepcopy__() соответственно.

Запомните эти 3 вещи

  1. Копирование с помощью присваивания (=) не создает новый объект, а только привязывает имя к существующему объекту.

  2. Поверхностная копия создает новый объект, содержащий ссылки на дочерние объекты оригинала.

  3. Глубокая копия создает полностью независимый клон объекта и всех его дочерних объектов.

Копирование объектов в Python - важный навык при работе с изменяемыми объектами или коллекциями. Надеюсь, данное объяснение поможет вам лучше понять, как создавать и использовать поверхностные и глубокие копии.