При объединении словарей через merge как определяется значение для совпавшего ключа?
Для совпавшего ключа merge вызывает переданное замыкание разрешения конфликта. В него передаются сначала уже существующее значение из словаря-приёмника, затем значение из добавляемого словаря; возвращённое замыканием значение становится итоговым.
Для ключей, которых ещё нет, значение добавляется напрямую. Метод merge изменяет словарь-приёмник на месте, тогда как merging создаёт новый словарь.
Словарь моделирует отображение ключа в одно значение, поэтому при объединении двух словарей одинаковый ключ не может сохранить оба значения одновременно. API merge решает эту проблему явно: разработчик задаёт правило разрешения конфликта вместо неявного выбора одного значения.
Такой подход подходит как для простого приоритета одного источника, так и для предметных правил: суммирования чисел, объединения наборов или выбора более свежей записи.
Если ключи пересекаются, простое объединение без правила не определяет, какое значение должно победить. Неверное направление приоритетов может привести к тому, что новые данные будут случайно перезаписаны старыми или наоборот.
Важно учитывать, что замыкание конфликта вызывается только для совпавших ключей. Для новых ключей оно не вызывается, поэтому побочные эффекты внутри этого замыкания зависят от структуры входных данных.
У merge словарь, на котором вызван метод, является источником уже существующих значений. Добавляемый словарь предоставляет входящие значения. При конфликте замыкание получает пару: текущее значение, входящее значение.
Например, чтобы новые данные имели приоритет, нужно вернуть второе значение:
После операции значение theme станет dark, а language будет добавлен. Если вернуть current, приоритет получит исходный словарь; если вернуть, например, сумму, правило конфликта будет предметным.
merge является изменяющим методом и не возвращает новый словарь как результат. merging имеет аналогичное правило разрешения конфликтов, но оставляет исходный словарь без изменений и возвращает объединённую копию.
Порядок обхода словаря не следует использовать как бизнес-правило: для фиксированного приоритета нужно явно выбрать первое или второе значение. Если операция должна обрабатывать ошибки, замыкание разрешения конфликта может быть бросающим, а ошибка будет передана вызывающему коду.
Приложение получает локальные настройки и обновления с сервера. Вариант без явного правила — присваивать значения в цикле; он плохо показывает приоритет источников и легко приводит к ошибке при изменении порядка обработки. Вариант с созданием промежуточных словарей через повторные копирования проще изолирует данные, но может быть менее эффективен и избыточен, если результат должен обновить существующее состояние.
Выбран merge с возвратом входящего значения: серверная конфигурация должна иметь приоритет над локальной. В результате новые ключи добавляются, совпадающие ключи заменяются предсказуемо, а исходный объект состояния не нужно заменять целиком.
Если же локальные изменения пользователя должны побеждать серверные, достаточно вернуть current. Для значений, которые нельзя просто заменить, например списков разрешений, замыкание может выполнить специальное объединение вместо выбора одного аргумента.
1. В каком порядке аргументы получает замыкание разрешения конфликта?
Первым передаётся текущее значение из словаря-приёмника, вторым — значение из добавляемого словаря. Поэтому возврат второго аргумента обычно означает приоритет входящих данных, а возврат первого — сохранение исходных данных. Перепутанное именование параметров может незаметно инвертировать бизнес-правило.
2. Вызывается ли замыкание для каждого элемента добавляемого словаря?
Нет. Оно вызывается только тогда, когда ключ уже существует в словаре-приёмнике. Для отсутствующего ключа значение вставляется непосредственно, поэтому нельзя использовать это замыкание как универсальный обработчик всех добавляемых элементов.
3. Чем практически отличаются merge и merging?
merge изменяет словарь, на котором вызван, и удобен для обновления уже существующего состояния без отдельного результата. merging возвращает новый словарь, сохраняя исходный; это предпочтительно, когда исходные данные должны оставаться неизменными или применяемая операция строится в функциональном стиле. Правило разрешения конфликтов у обоих методов задаётся одинаковой идеей — через замыкание, возвращающее итоговое значение.