Исключения в Python: raise ... from и атрибут __cause__

Исключения в Python: raise ... from и атрибут __cause__

@python_quiz

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

Коротко: в примере используется явная цепочка исключений через raise ... from. Это сохраняет исходное исключение в атрибуте __cause__ у нового исключения.

Исходный код

python

Этот фрагмент печатает тип пойманного исключения и тип его __cause__.

Что делает raise ... from

  • raise NewError(...) from original_exc создаёт новое исключение NewError и явно связывает его с original_exc.
  • Связь хранится в NewError.__cause__.
  • Если from не указан, интерпретатор автоматически сохраняет предыдущее исключение в __context__ (если исключение произошло во время обработки другого), а __cause__ остаётся None.
  • Можно подавить автоматический контекст с помощью from None — тогда __context__ не будет отображаться в трассировке.

Вывод программы

Программа выведет:

Пояснение: в except переменная e — объект ConfigError, а e.__cause__ — объект FileNotFoundError.

Анализ вариантов (почему одни совпадают, а другие — нет)

  • "ConfigError -> FileNotFoundError" — соответствует выводу. Первое слово — имя класса внешнего исключения, второе — имя класса причины.
  • "ConfigError -> None" — имело бы место, если бы from не использовался. Тогда __cause__ был бы None, а исходное исключение попало бы в __context__.
  • "FileNotFoundError -> ConfigError" — обратный порядок: здесь предполагается, что поймано бы первоначальное исключение, а причина — новое. В данном коде это не так: новое исключение — внешний уровень.
  • "Exception -> FileNotFoundError" — неверно, потому что тип e — конкретный класс ConfigError, а не общий Exception. Вывод функции type(e).__name__ даст именно ConfigError.

Наглядные эксперименты

1) Поведение без from (исходное исключение в __context__):

python

Вывод покажет, что __cause__None, а __context__FileNotFoundError.

2) Подавление контекста (from None):

python

Здесь контекст не отображается и __cause__ остаётся None.

Вывод

Использование raise ... from явно связывает исключения через __cause__. В рассматриваемом фрагменте это даёт вывод "ConfigError -> FileNotFoundError" — внешний класс исключения и класс его причины. Это удобный механизм для создания более понятных и контролируемых трассировок ошибок в коде.

Report Page