¿Cuál es la diferencia entre raise
y raise from
en Python?
try:
raise ValueError
except Exception as e:
raise IndexError
cuyos rendimientos
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
y
try:
raise ValueError
except Exception as e:
raise IndexError from e
cuyos rendimientos
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
python
python-3.x
syntax
exception-handling
darkfeline
fuente
fuente
raise IndexError from None
, digamos.raise IndexError from False
plantea unTypeError
, no unIndexError
. Me alegró el día.Respuestas:
La diferencia es que cuando usa
from
, el__cause__
atributo se establece y el mensaje indica que la excepción fue causada directamente por . Si omite,from
entonces no__cause__
se establece, pero el__context__
atributo también se puede establecer, y el rastreo luego muestra el contexto como durante el manejo de que sucedió algo más .Establecer lo que
__context__
sucede si lo usóraise
en un controlador de excepciones; si lo usó enraise
cualquier otro lugar, tampoco__context__
está configurado.Si
__cause__
se establece a,__suppress_context__ = True
también se establece un indicador en la excepción; cuando__suppress_context__
se establece enTrue
,__context__
se ignora al imprimir un rastreo.Cuando se plantea desde un manejador de excepción en el que no desea mostrar el contexto (no quiero una durante la manipulación otra excepción ocurrió mensaje), a continuación, utilizar
raise ... from None
al conjunto__suppress_context__
aTrue
.En otras palabras, Python establece un contexto de excepciones para que pueda introspectar dónde se generó una excepción, permitiéndole ver si otra excepción fue reemplazada por ella. También puede agregar una causa a una excepción, haciendo que el rastreo sea explícito sobre la otra excepción (use una redacción diferente), y el contexto se ignora (pero aún puede ser introspectado al depurar). El uso le
raise ... from None
permite suprimir el contexto que se imprime.Vea la
raise
documentación de la declaración :Consulte también la documentación de Excepciones incorporadas para obtener detalles sobre el contexto y la información de causa adjunta a las excepciones.
fuente
from
y__cause__
en lugar de lo implícito__context__
? ¿Hay algún caso en el que se adjunte una excepción diferente a la capturada por elexcept
?DatabaseError
error si la apertura de la base de datos falla. Pero si la falla es el resultado de unIOError
porque un archivo no se pudo abrir oHTTPError
porque una URL no funcionó, entonces ese es el contexto que desea incluir explícitamente, por lo que el desarrollador que usa la API puede depurar por qué esto es así. En ese momento lo usasraise DatabaseError from original_exception
.IOError
niHTTPError
a sus consumidores, entonces tendrían que su usoraise NewException from databaseexception.__cause__
, ahora usando una excepción diferente de laDatabaseException
que sólo atrapados.foo
y quieres generar una nueva excepciónbar
? Entonces puede usarraise bar from foo
y tener el estado de Python quefoo
causó directamentebar
. Si no lo usafrom foo
, Python seguirá imprimiendo ambos, pero indique que durante el manejofoo
,bar
se generó un mensaje diferente, destinado a marcar un posible error en el manejo del error.