Оператор raise

Оновлено: 24.04.2023

raise_stmt ::=  "raise" [expression ["from" expression]]

Якщо виразів немає, raise повторно викликає виняток, який зараз обробляється, який також відомий як активний виняток. Якщо наразі немає активного винятку, виникає виняток RuntimeError, який вказує на те, що це помилка.

В іншому випадку raise обчислює перший вираз як об’єкт винятку. Це має бути або підклас, або екземпляр BaseException. Якщо це клас, екземпляр винятку буде отримано за потреби шляхом створення екземпляра класу без аргументів.

type винятку — це клас екземпляра винятку, value — це сам екземпляр.

Об’єкт трасування зазвичай створюється автоматично, коли виникає виняток і додається до нього як атрибут __traceback__, який доступний для запису. Ви можете створити виняток і встановити власну трасування одним кроком за допомогою методу винятку with_traceback() (який повертає той самий екземпляр винятку, з його трасуванням, встановленим для його аргументу), наприклад:

raise Exception("foo occurred").with_traceback(tracebackobj)

Речення from використовується для ланцюжка винятків: якщо задано, другий вираз має бути іншим класом винятків або екземпляром. Якщо другий вираз є екземпляром винятку, його буде приєднано до викликаного винятку як атрибут __cause__ (який доступний для запису). Якщо вираз є класом винятку, екземпляр класу буде створено, а отриманий екземпляр винятку буде додано до викликаного винятку як атрибут __cause__. Якщо викликаний виняток не оброблено, обидва виключення будуть надруковані:

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Подібний механізм працює неявно, якщо виникає новий виняток, коли виняток уже обробляється. Виняток може бути оброблено, коли використовується речення except або finally або оператор with. Потім попередній виняток додається як атрибут __context__ нового винятку:

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Ланцюжки винятків можна явно придушити, вказавши None у пункті from:

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened") from None
...
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Додаткову інформацію про винятки можна знайти в розділі Винятки, а інформацію про обробку винятків — у розділі Оператор try.