Різниця полягає в тому, що при використанні from
, то __cause__
атрибут встановлений , і повідомлення заявляє , що виключення було безпосередньо викликано . Якщо ви не увімкнете, from
тоді не __cause__
встановлено "ні", але може бути встановлено також __context__
атрибут , а відслідковування назад показує контекст, як під час обробки чогось іншого трапилося .
Налаштування __context__
відбувається, якщо ви використовували raise
обробник винятків; якщо ви використовували raise
інше місце, також не __context__
встановлено.
Якщо __cause__
встановлено a, __suppress_context__ = True
на винятку також встановлюється прапор; коли __suppress_context__
встановлено значення True
, __context__
ігнорується при друкуванні сліду.
Піднімаючи з обробника винятків, де ви не хочете показувати контекст (не хочу, щоб під час обробки іншого повідомлення про виняток трапилося ), тоді використовуйте raise ... from None
для встановлення __suppress_context__
на True
.
Іншими словами, Python встановлює контекст на винятки, щоб ви могли переглядати, де виняток був піднятий, дозволяючи побачити, чи замінили його інший виняток. Ви також можете додати причину до винятку, зробивши прослідкування явним про інший виняток (використовуйте різні формулювання), а контекст ігнорується (але все ще може бути інтроспективним при налагодженні). Використання raise ... from None
дозволяє придушити друк контексту.
Дивіться документацію raise
твердження :
from
Розділ використовується для виключення зчеплення: якщо дано, друге вираз має бути іншим клас виключення або екземпляр, який потім буде приєднаний до підвищеного виключенню в якості __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: int division or modulo 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
Подібний механізм працює неявно, якщо виняток піднімається всередині обробника винятків або finally
пункту: попередній виняток потім додається як __context__
атрибут нового винятку :
>>> try:
... print(1 / 0)
... except:
... raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo 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
Також дивіться документацію про вбудовані винятки, щоб отримати детальну інформацію про контекст та викликати інформацію, що додається до винятків.