web-dev-qa-db-fra.com

Python "relance de" utilisation

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
138
darkfeline

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.

162
Martijn Pieters