La différence est que lorsque vous utilisez from, l' __cause__attribut est défini et le message indique que l'exception a été directement causée par . Si vous omettez, fromalors no __cause__est défini, mais l' __context__attribut peut également être défini et le suivi affiche alors le contexte comme lors de la gestion de quelque chose d'autre s'est produit .
La définition de __context__se produit si vous avez utilisé raisedans un gestionnaire d'exceptions; si vous avez utilisé raisen'importe où ailleurs, no __context__est défini non plus.
Si a __cause__est défini, un __suppress_context__ = Trueindicateur est également défini sur l'exception; lorsque __suppress_context__est défini sur True, le __context__est ignoré lors de l'impression d'une trace.
Lorsque vous déclenchez à partir d'un gestionnaire d'exceptions où vous ne voulez pas afficher le contexte (ne voulez pas qu'un message lors de la gestion d'une autre exception s'est produit ), utilisez raise ... from Nonepour définir __suppress_context__sur True.
En d'autres termes, Python définit un contexte sur les exceptions afin que vous puissiez introspecter où une exception a été déclenchée, vous permettant de voir si une autre exception a été remplacée par elle. Vous pouvez également ajouter une cause à une exception, en rendant le traçage explicite sur l'autre exception (utilisez un libellé différent), et le contexte est ignoré (mais peut toujours être introspectionné lors du débogage). L'utilisation raise ... from Nonevous permet de supprimer le contexte en cours d'impression.
Voir la documentation de la raisedéclaration :
La fromclause est utilisée pour le chaînage des exceptions: si elle est donnée, la deuxième expression doit être une autre classe ou instance d'exception, qui sera ensuite attachée à l'exception levée en tant __cause__qu'attribut (qui est accessible en écriture). Si l'exception levée n'est pas gérée, les deux exceptions seront imprimées:
>>> 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 mécanisme similaire fonctionne implicitement si une exception est déclenchée à l'intérieur d'un gestionnaire d'exceptions ou d'une finallyclause: l'exception précédente est alors attachée en tant __context__qu'attribut de la nouvelle exception :
>>> 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
Consultez également la documentation sur les exceptions intégrées pour plus de détails sur le contexte et les informations de cause attachées aux exceptions.