Что такое глубокое копирование в Python?

«Что такое глубокое копирование в Python?» — вопрос из категории Python, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Глубокое копирование (deep copy) — это создание нового составного объекта (например, списка списков, словаря со вложенными словарями) и рекурсивное копирование всех объектов, найденных в исходном, делая копию полностью независимой от оригинала. Изменения во вложенных объектах оригинала не затронут копию, и наоборот.

Почему это важно в тестировании на Python? Часто нужно подготовить тестовые данные (фикстуры), модифицировать их в тесте, но при этом сохранить исходное состояние для других тестов или для сравнения "до/после". Поверхностное копирование (copy.copy() или list()) здесь подведет.

Пример проблемы и решения:

import copy

# Исходные тестовые данные (сложная структура)
test_config_original = {
    'server': {'host': 'localhost', 'port': 8080},
    'users': [{'id': 1, 'role': 'admin'}, {'id': 2, 'role': 'tester'}]
}

# ПОВЕРХНОСТНОЕ копирование (опасно!)
test_config_shallow = copy.copy(test_config_original)
# ИЛИ test_config_shallow = dict(test_config_original)

# ГЛУБОКОЕ копирование (правильно для независимой копии)
test_config_deep = copy.deepcopy(test_config_original)

# Модифицируем вложенный объект в "копии"
test_config_shallow['server']['port'] = 9999  # Меняет ОРИГИНАЛ!
test_config_deep['users'][0]['role'] = 'superuser'  # Не меняет оригинал

print("Original:", test_config_original['server']['port'])  # 9999 (!)
print("Original user role:", test_config_original['users'][0]['role'])  # 'admin' (ok)

Когда использовать deepcopy в автотестах:

  • Подготовка изолированных фикстур для параметризованных тестов.
  • Эмуляция состояния данных "до выполнения операции" для последующего сравнения.
  • Создание модифицированных конфигов для тестирования разных сценариев на основе базового.

Минус: deepcopy работает медленнее и потребляет больше памяти, чем поверхностное копирование, поэтому для простых, одноуровневых структур оно избыточно.