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, from
alors 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é raise
dans un gestionnaire d'exceptions; si vous avez utilisé raise
n'importe où ailleurs, no __context__
est défini non plus.
Si a __cause__
est défini, un __suppress_context__ = True
indicateur 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 None
pour 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 None
vous permet de supprimer le contexte en cours d'impression.
Voir la documentation de la raise
déclaration :
La from
clause 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 finally
clause: 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.