Різниця полягає в тому, що при використанні 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
Також дивіться документацію про вбудовані винятки, щоб отримати детальну інформацію про контекст та викликати інформацію, що додається до винятків.