La differenza è che quando si utilizza froml' __cause__attributo viene impostato e il messaggio indica che l'eccezione è stata causata direttamente da . Se si omette, fromallora __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 raisein un gestore eccezioni; se hai usato raisealtrove, non __context__è impostato neanche.
Se __cause__viene impostato a, __suppress_context__ = Trueviene 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 Noneper 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 Noneconsente di sopprimere il contesto in fase di stampa.
Vedi la raisedocumentazione dichiarazione :
La fromclausola 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 finallyclausola: 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.