Как правильно добавлять один ключ в словарь в Python: update или создание нового словаря
Что проверяют
Знаете ли вы разницу между изменением словаря на месте и созданием нового, и понимаете ли, чем она оборачивается в тестах. Следом обычно спрашивают про поверхностную копию: что будет с вложенным словарём после {**d}.
Как отвечать
Для одного ключа ни update, ни новый словарь не нужны: самый простой и быстрый способ это присваивание d["token"] = value. Оно работает за O(1) в среднем и не создаёт временных объектов. Дальше выбор зависит от того, можно ли менять исходный словарь:
d.update(...): меняет словарь на месте, удобен для нескольких ключей сразу, принимает словарь, пары или именованные аргументыd.update(token=value). ВозвращаетNone;- `{d, "token": value}`**: новый словарь, исходный не тронут. Копирование стоит O(n) по числу ключей;
d | {"token": value}: то же самое, оператор объединения появился в Python 3.9. Его параd |= {...}снова меняет на месте;d.setdefault(key, default): добавит ключ, только если его ещё нет.
В QA это не академический вопрос. Базовый payload для API-тестов, словарь заголовков или конфиг часто живут в фикстуре или константе модуля. Если тест мутирует их, следующий тест получает уже изменённые данные и падает или, хуже, проходит случайно. Правило такое: общие данные не меняем, а собираем из них вариант под тест через {**base, ...} или фабрику вроде make_payload(**overrides). Для фикстуры pytest со scope="module" или scope="session" это особенно важно: объект один на все тесты.
Где спотыкаются
Пишут payload = base.update({"id": 1}) и получают None, потому что update ничего не возвращает.
Считают, что {**d} или d.copy() копирует всё. Копия поверхностная: вложенный словарь d["user"] остаётся общим, и его правка протекает в оригинал. Для вложенных структур нужен copy.deepcopy.
Передают через именованные аргументы любые ключи. Так работают только ключи, которые являются корректными идентификаторами Python, а заголовок вроде Content-Type в update(...) без словаря даст синтаксическую ошибку.