Превращение предупреждений в исключения в Python
@python_quizРазберем этот квиз
Коротко: в приведённом коде предупреждение превращается в исключение и поэтому в блоке except выполняется печать A. Ниже — разбор почему так происходит, что важно учитывать и несколько наглядных примеров.
Условие (исходный код)

Ключевая идея
warnings.warn('test')по умолчанию использует категориюUserWarning.warnings.filterwarnings('error', category=UserWarning)переводит срабатывание предупреждений категорииUserWarningв бросание соответствующего исключения (т.е.warnings.warnтеперь поднимет исключениеUserWarningвместо печати предупреждения).except Warning:перехватывает исключениеUserWarning, потому чтоUserWarningявляется подклассомWarning.- Следовательно, управление перейдёт в блок
exceptи будет выведеноA. Блокelseпри этом выполняться не будет.
Разбор вариантов ответов (логика)
- "Выведет: A" — соответствует описанному поведению: предупреждение стало исключением и было поймано.
- "Выведет: B" — могло бы быть правдой, если бы предупреждение не было превращено в исключение (т.е. без
filterwarnings('error', ...)): тогдаwarnings.warnне бросит исключение,tryзавершится нормально и выполнитсяelse. - "Ничего не выведет" — неверно: либо будет напечатано предупреждение (обычное поведение без фильтра), либо произойдёт захват исключения и будет напечатано
A, либо (редко) программа аварийно завершится, если исключение не перехвачено. - "Будет напечатано предупреждение, но без A/B" — неверно в текущем коде, потому что фильтр принудительно превращает предупреждение в исключение; печать предупреждения вместо исключения произойдёт только если не было вызова
filterwarnings('error', ...)для соответствующей категории.
Демонстрации и вариации
1) Поведение с фильтром (как в условии):

Вывод: A
2) Поведение без фильтра:

Вывод: B (и появится сообщение-предупреждение в STDERR)
3) Перехват конкретной категории:

4) Альтернативный способ включить поведение "error":
- Через функцию
warnings.simplefilter('error')— задаёт правило для всех категорий по умолчанию. - Через системный флаг при запуске Python:
python -W error::UserWarning script.py.
На что обратить внимание
- Порядок важен: фильтр должен быть установлен до вызова
warnings.warn. - Можно таргетировать конкретные категории предупреждений (например,
DeprecationWarning,SyntaxWarningи т.д.). - Перевод предупреждений в исключения полезен при тестировании, чтобы избежать игнорирования важных сигналов в рантайме.
Вывод
В рассматриваемом коде предупреждение категории UserWarning преобразуется в исключение, которое перехватывается блоком except Warning. В результате программа печатает строку A.