Qual é a diferença entre raise
e raise from
no Python?
try:
raise ValueError
except Exception as e:
raise IndexError
que produz
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
e
try:
raise ValueError
except Exception as e:
raise IndexError from e
que produz
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
fonte
fonte
raise IndexError from None
, digamos.raise IndexError from False
gera umTypeError
, não umIndexError
. Fez o meu dia.Respostas:
A diferença é que, quando você usa
from
, o__cause__
atributo é definido e a mensagem informa que a exceção foi causada diretamente por . Se você omitir,from
então não__cause__
será definido, mas o__context__
atributo também poderá ser definido, e o rastreamento mostrará o contexto como durante o tratamento de algo que aconteceu .Definir o que
__context__
acontece se você usouraise
em um manipulador de exceções; se você usou emraise
qualquer outro lugar, também não__context__
está definido.Se a
__cause__
estiver definido, um__suppress_context__ = True
sinalizador também será definido na exceção; Quando__suppress_context__
está definido comoTrue
, o__context__
é ignorado ao imprimir um retorno.Ao passar de um manipulador de exceções no qual você não deseja mostrar o contexto (não deseje uma mensagem durante o tratamento de outra exceção ), use
raise ... from None
para definir__suppress_context__
comoTrue
.Em outras palavras, o Python define um contexto para exceções, para que você possa examinar onde uma exceção foi gerada, permitindo ver se outra exceção foi substituída por ela. Você também pode adicionar uma causa a uma exceção, explicitando explicitamente o traceback sobre a outra exceção (use palavras diferentes) e o contexto é ignorado (mas ainda pode ser observado durante a depuração). Usar
raise ... from None
permite suprimir o contexto que está sendo impresso.Veja a
raise
documentação documentada :Consulte também a documentação de exceções internas para obter detalhes sobre o contexto e causar informações anexadas a exceções.
fonte
from
e__cause__
no lugar do implícito__context__
? Existem casos em que alguém anexaria uma exceção diferente daquela detectada peloexcept
?DatabaseError
se a abertura do banco de dados falhar. Mas se a falha for o resultado de umIOError
porque um arquivo falhou ao abrir ou umHTTPError
URL não funcionou, esse é o contexto que você deseja incluir explicitamente, para que o desenvolvedor que usa a API possa depurar o motivo. Nesse momento você usaraise DatabaseError from original_exception
.IOError
ouHTTPError
para seus consumidores, eles teriam que usarraise NewException from databaseexception.__cause__
, agora usando uma exceção diferenteDatabaseException
daquela que acabaram de capturar.foo
e quer criar uma nova exceçãobar
? Então você pode usarraise bar from foo
e ter o estado Python quefoo
causou diretamentebar
. Se você não usarfrom foo
, o Python ainda imprimirá os dois, mas declare que durante o manuseiofoo
,bar
foi gerada uma mensagem diferente, destinada a sinalizar um possível bug no manuseio de erros.