Quelle est la différence entre raise
et raise from
en Python?
try:
raise ValueError
except Exception as e:
raise IndexError
qui donne
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError
IndexError
et
try:
raise ValueError
except Exception as e:
raise IndexError from e
qui donne
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError from e
IndexError
La différence est que lorsque vous utilisez from
, l'attribut __cause__
est défini et le message indique que l'exception était directement causée par. Si vous omettez le from
alors aucun __cause__
N'est défini, mais l'attribut __context__
peut également être défini, et la trace affiche ensuite le contexte comme lors de la manipulation, quelque chose d'autre s'est passé.
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, aucun __context__
n'est défini.
Si un __cause__
Est défini, un indicateur __suppress_context__ = True
Est également défini sur l'exception; Lorsque __suppress_context__
est défini sur True
, le __context__
est ignoré lors de l'impression d'un suivi.
Lors de la levée depuis un gestionnaire d'exceptions où vous non voulez afficher le contexte (vous ne voulez pas de lors de la gestion d'une autre exception s'est produite message), puis utilisez raise ... from None
Pour définir __suppress_context__
Sur True
.
En d'autres termes, Python définit un contexte sur les exceptions afin de vous permettre de faire l'introspective lorsqu'une exception a été déclenchée, vous permettant ainsi de voir si une autre exception a été remplacée par elle. Vous pouvez également ajouter un cause à une exception, ce qui rend le suivi explicite sur l'autre exception (utilisez un libellé différent) et le contexte est ignoré (mais peut toujours être introspecté lors du débogage). L'utilisation de raise ... from None
Vous permet de supprimer le contexte en cours d'impression.
Voir la raise
documenation statement :
La clause
from
est utilisée pour le chaînage des exceptions: si elle est donnée, la seconde expression doit être une autre classe ou instance d’exception, qui sera ensuite jointe à l’exception levée sous la forme__cause__
Attribut (qui est 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 dans un gestionnaire d’exception ou une clause
finally
: l’exception précédente est alors attachée en tant qu’attribut__context__
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
Reportez-vous également à la section Documentation sur les exceptions intégrées pour plus de détails sur le contexte et les informations de cause associées aux exceptions.