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, fromentã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ê usou raiseem um manipulador de exceções; se você usou em raisequalquer outro lugar, também não __context__está definido.
Se a __cause__estiver definido, um __suppress_context__ = Truesinalizador também será definido na exceção; Quando __suppress_context__está definido como True, 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 Nonepara definir __suppress_context__como True.
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 Nonepermite suprimir o contexto que está sendo impresso.
Veja a raisedocumentação documentada :
A fromcláusula é usada para o encadeamento de exceções: se fornecida, a segunda expressão deve ser outra classe ou instância de exceção, que será anexada à exceção gerada como o __cause__atributo (que é gravável). Se a exceção levantada não for tratada, as duas exceções serão impressas:
>>> 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
Um mecanismo semelhante funciona implicitamente se uma exceção é gerada dentro de um manipulador ou finallycláusula de exceção: a exceção anterior é anexada como o novo __context__atributo da exceção :
>>> 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
Consulte também a documentação de exceções internas para obter detalhes sobre o contexto e causar informações anexadas a exceções.