La differenza è che quando si utilizza from
l' __cause__
attributo viene impostato e il messaggio indica che l'eccezione è stata causata direttamente da . Se si omette, from
allora __cause__
viene impostato no , ma è possibile impostare anche l' __context__
attributo e il traceback mostra quindi il contesto come durante la gestione di qualcos'altro .
L'impostazione __context__
succede se è stato utilizzato raise
in un gestore eccezioni; se hai usato raise
altrove, non __context__
è impostato neanche.
Se __cause__
viene impostato a, __suppress_context__ = True
viene impostato anche un flag sull'eccezione; quando __suppress_context__
è impostato su True
, __context__
viene ignorato quando si stampa un traceback.
Quando si solleva da un gestore di eccezioni in cui non si desidera mostrare il contesto (non si desidera durante la gestione di un altro messaggio si è verificata un'eccezione ), quindi utilizzare raise ... from None
per impostare __suppress_context__
su True
.
In altre parole, Python imposta un contesto sulle eccezioni in modo da poter introspettare dove è stata sollevata un'eccezione, consentendo di vedere se un'altra eccezione è stata sostituita da essa. È inoltre possibile aggiungere una causa a un'eccezione, rendendo esplicito il traceback sull'altra eccezione (utilizzare una diversa formulazione) e il contesto viene ignorato (ma può comunque essere introspetto durante il debug). L'uso raise ... from None
consente di sopprimere il contesto in fase di stampa.
Vedi la raise
documentazione dichiarazione :
La from
clausola viene utilizzata per il concatenamento delle eccezioni: se fornita, la seconda espressione deve essere un'altra classe o istanza di eccezione, che verrà quindi allegata all'eccezione sollevata come __cause__
attributo (che è scrivibile). Se l'eccezione sollevata non viene gestita, verranno stampate entrambe le eccezioni:
>>> 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
Un meccanismo simile funziona implicitamente se viene sollevata un'eccezione all'interno di un gestore di eccezioni o di una finally
clausola: l'eccezione precedente viene quindi allegata come __context__
attributo della nuova eccezione :
>>> 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
Vedere anche la documentazione Eccezioni incorporate per dettagli sul contesto e causare informazioni allegate alle eccezioni.