Превращение предупреждений в исключения в Python

Превращение предупреждений в исключения в Python

@python_quiz

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

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

Условие (исходный код)

python

Ключевая идея

  • 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) Поведение с фильтром (как в условии):

python

Вывод: A

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

python

Вывод: B (и появится сообщение-предупреждение в STDERR)

3) Перехват конкретной категории:

python

4) Альтернативный способ включить поведение "error":

  • Через функцию warnings.simplefilter('error') — задаёт правило для всех категорий по умолчанию.
  • Через системный флаг при запуске Python: python -W error::UserWarning script.py.

На что обратить внимание

  • Порядок важен: фильтр должен быть установлен до вызова warnings.warn.
  • Можно таргетировать конкретные категории предупреждений (например, DeprecationWarning, SyntaxWarning и т.д.).
  • Перевод предупреждений в исключения полезен при тестировании, чтобы избежать игнорирования важных сигналов в рантайме.

Вывод

В рассматриваемом коде предупреждение категории UserWarning преобразуется в исключение, которое перехватывается блоком except Warning. В результате программа печатает строку A.

Report Page