Как from __future__ import annotations влияет на __annotations__
@python_quizРазберем этот квиз
Коротко — в примере аннотации сохраняются не как объекты типов, а как строки. Ниже разберём код, покажем вывод и проанализируем возможные варианты ответа.
Исходный код

Этот фрагмент присутствовал в условии квиза. Обратите внимание на from __future__ import annotations и на использование | для объединения типов (PEP 604).
Что делает from __future__ import annotations
- Этот импорт включает отложенную (postponed) оценку аннотаций (PEP 563). Вместо реальных объектов типов в
__annotations__сохраняются строковые представления исходных аннотаций. - Это полезно, чтобы избежать импортных зависимостей во время определения функций/классов и ускорить время импорта.
- Для получения "реальных" объектов типов из таких строк используют
typing.get_type_hints()(он выполнит безопасную оценку аннотаций).
Ожидаемый вывод
При запуске приведённого кода __annotations__ будет выглядеть так:

То есть значения в словаре — строки с текстовым представлением аннотаций, а не сами объекты типа int или объединённого типа int | str.
Анализ вариантов ответа
Допустим, в квизе были такие варианты (привожу их как текст):
- {'x': int, 'y': int, 'return': int}
Пояснение: значения — объекты типа int. В рассматриваемом примере это неверно — аннотации описывают объединение int | str, да и при отложенной оценке они хранятся как строки.
- {'x': 'int | str', 'y': 'int | str', 'return': 'int | str'}
Пояснение: строки с текстовым представлением аннотаций. Это именно то, что сохраняется в __annotations__, когда включён from __future__ import annotations.
- {'x': int | str, 'y': int | str, 'return': int | str}
Пояснение: объекты объединённого типа (PEP 604). Такой результат мог бы наблюдаться, если бы аннотации не были отложены и Python при парсинге создал бы реальные объекты объединений. Но с отложенной оценкой в __annotations__ попадут строки, а не вычисленные объекты.
- {}
Пояснение: пустой словарь. Появляется только если аннотаций нет или они удалены; в нашем примере аннотации явно присутствуют, так что этот вариант не соответствует реальности.
Как получить реальные типы из отложённых аннотаций
Если нужно преобразовать строковые аннотации в реальные объекты типов, используют typing.get_type_hints():

Примерный вывод при исполнении на Python 3.10+:

Замечания:
- Чтобы
get_type_hints()корректно преобразовал выражения, интерпретатор должен понимать используемый синтаксис аннотаций (например,|для объединения требует Python 3.10+). - При сложных аннотациях (ссылающихся на имена из других модулей)
get_type_hints()может потребовать корректные глобальные/локальные пространства имён или импортов.
Вывод
from __future__ import annotationsзаставляет Python сохранять аннотации как строки в__annotations__.- Поэтому в рассматриваемом примере словарь
__annotations__содержит строковые записи вида'int | str'. - Для получения реальных объектов типов используйте
typing.get_type_hints().