Работал ли с методом deepcopy в Python?

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

Ответ

Да, использовал deepcopy из модуля copy в тестах, когда необходимо было создать полностью независимую копию сложного тестового объекта для модификации.

Типичный кейс в автотестах:

Представьте, что у вас есть фикстура default_order, возвращающая словарь с вложенными структурами (списками товаров, словарями с данными клиента). Вам нужно в нескольких тестах использовать эту базовую структуру, но с разными модификациями.

import copy
import pytest

@pytest.fixture
def default_order():
    return {
        "id": 1,
        "customer": {"name": "John", "loyalty_points": 100},
        "items": [
            {"sku": "A123", "qty": 2, "price": 50.0},
            {"sku": "B456", "qty": 1, "price": 30.0}
        ],
        "status": "NEW"
    }

# ТЕСТ 1: Проверяем расчет скидки для лояльного клиента
# Мы хотим изменить только баллы, не трогая оригинальную фикстуру для других тестов
def test_loyalty_discount(default_order):
    order_for_test = copy.deepcopy(default_order)  # Создаем глубокую копию
    order_for_test["customer"]["loyalty_points"] = 500  # Меняем копию
    discount = calculate_discount(order_for_test)
    assert discount == 25.0  # Ожидаемая скидка 5%
    # default_order остался неизменным: loyalty_points = 100

# ТЕСТ 2: Проверяем добавление нового товара в заказ
def test_add_item(default_order):
    order_for_test = copy.deepcopy(default_order)  # Новая независимая копия
    new_item = {"sku": "C789", "qty": 3, "price": 10.0}
    order_for_test["items"].append(new_item)  # Добавляем в копию
    total = calculate_total(order_for_test)
    assert total == 170.0  # 2*50 + 1*30 + 3*10
    # default_order остался с двумя исходными товарами

Почему deepcopy, а не copy() или присваивание? Присваивание (order_for_test = default_order) создает лишь новую ссылку на тот же объект. Поверхностное копирование (copy.copy()) скопирует только верхний уровень словаря, но вложенные списки и словари (items, customer) останутся общими. deepcopy рекурсивно копирует всё, гарантируя полную изоляцию тестовых данных и предотвращая хрупкие тесты, которые ломаются из-за неожиданных изменений состояния.