Почему .format с {user['name']!r} приводит к KeyError

Почему .format с {user['name']!r} приводит к KeyError

@python_quiz

Разберем этот квиз

Коротко: исходный код падает с KeyError. Причина — не в !r и не в f-строке, а в том, как метод str.format парсит содержимое фигурных скобок.

Исходный код

python

При запуске этот код не дойдет до вывода — .format вызовет исключение.

Что именно происходит и почему

  • f-строка (f"...") — это полноценный парсер Python-выражений: внутри можно писать любые выражения Python, включая индексирование словаря с кавычками, т.е. user['name'] корректно.
  • Оператор форматирования %r использует старый стиль и просто применяет repr к аргументу — тоже работает с user['name'].
  • str.format имеет собственный синтаксис для полей: внутри фигурных скобок указывается имя поля и опциональные обращения .attr или [index]. При индексировании ключи в квадратных скобках НЕ берутся в кавычки: нужно писать {user[name]}, а не {user['name']}. Если в скобках есть кавычки, форматтер воспринимает их как часть имени ключа, и будет искать ключ, который включает кавычки в имени (например, "'name'"), которого в словаре нет — в результате KeyError.

Именно поэтому конструкция "{user['name']!r}".format(user=user) завершится KeyError.

Демонстрация исправлений и эквивалентных вариантов

Правильные способы получить repr значения обоими подходами:

python

Все эти варианты напечатают одинаковую строку (repr значения) — но важно, что для str.format ключи внутри [ ] должны быть без кавычек.

Разбор вариантов ответа (анализ)

  • "Выведет три одинаковые строки с кавычками вокруг имени" — это могло бы быть верно, если бы .format-поле было записано корректно, но в приведенном коде .format вызывает исключение и вывода нет.
  • "f-строка и %r дадут одинаковый repr; ошибка не в !r" — верно в части, что f-строка и %r действительно используют repr и вернут одинаковый результат. Но причина падения — не в !r, а в синтаксисе поля .format.
  • "Все три части выведут имя без кавычек" — неверно: f-строка с !r и %r дают repr с кавычками; форматирование без !r (или использование str) дало бы без кавычек. В любом случае, исходный код не выводит ничего из-за исключения.
  • "Код упадёт с KeyError: .format парсит {user['name']!r} как поле с кавычками, поэтому доступа нет" — это точное объяснение причины падения: внутри .format кавычки в индексе воспринимаются как часть имени ключа, ключ не найден, возникает KeyError.

Выводы и рекомендации

  • Помните, что синтаксис внутри f-строк — это Python-выражения; синтаксис внутри str.format — свой, с более простым парсингом полей.
  • Для обращения к словарю в format используйте {user[name]} (без кавычек) или распаковывайте словарь в именованные аргументы: "{name}".format(**user).
  • Если нужен repr, используйте !r в f-строках или в полях format: "{name!r}".format(**user).

Report Page