Quero salvar o nome do erro e os detalhes do rastreamento em uma variável. Aqui está a minha tentativa.
import sys
try:
try:
print x
except Exception, ex:
raise NameError
except Exception, er:
print "0", sys.exc_info()[0]
print "1", sys.exc_info()[1]
print "2", sys.exc_info()[2]
Resultado:
0 <type 'exceptions.NameError'>
1
2 <traceback object at 0xbd5fc8>
Saída desejada:
0 NameError
1
2 Traceback (most recent call last):
File "exception.py", line 6, in <module>
raise NameError
PS: Sei que isso pode ser feito facilmente usando o módulo traceback, mas quero saber o uso do objeto sys.exc_info () [2] aqui.
python
exception-handling
codersofthedark
fonte
fonte
<python install path>/Lib/traceback.py
) para obter mais informações.Respostas:
É assim que eu faço:
No entanto, você deve dar uma olhada na documentação do traceback , pois poderá encontrar métodos mais adequados, dependendo de como deseja processar sua variável posteriormente ...
fonte
sys.exc_info()[2].tb_frame.f_code.co_names[3]
, mas faz qualquer sentido ... Se houver um módulo chamadotraceback
na biblioteca padrão, há uma razão para isso ... :)traceback.format_exception(*sys.exc_info())
é a maneira de fazê-lo. Mas isso é funcionalmente equivalente atraceback.format_exc()
.sys.exc_info () retorna uma tupla com três valores (tipo, valor, retorno).
Por exemplo, no programa a seguir
Agora Se imprimirmos a tupla, os valores serão esses.
Os detalhes acima também podem ser buscados simplesmente imprimindo a exceção no formato de sequência.
fonte
Use
traceback.extract_stack()
se desejar acesso conveniente aos nomes dos módulos e das funções e aos números de linha.Use
''.join(traceback.format_stack())
se você quiser apenas uma sequência que se pareça com atraceback.print_stack()
saída.Observe que, mesmo com
''.join()
você, obterá uma sequência de linhas múltiplas, pois os elementos deformat_stack()
contêm\n
. Veja a saída abaixo.Lembre-se de
import traceback
.Aqui está a saída de
traceback.extract_stack()
. Formatação adicionada para facilitar a leitura.Aqui está a saída de
''.join(traceback.format_stack())
. Formatação adicionada para facilitar a leitura.fonte
Tenha cuidado ao remover o objeto de exceção ou o objeto de retorno do manipulador de exceções, pois isso causa referências circulares e
gc.collect()
não será possível coletar. Isso parece ser um problema específico no ambiente de notebook ipython / jupyter, em que o objeto traceback não é limpo no momento certo e mesmo uma chamada explícitagc.collect()
nafinally
seção não faz nada. E isso é um problema enorme se você tiver alguns objetos enormes que não recuperam a memória por causa disso (por exemplo, exceções de falta de memória CUDA que sem esta solução exigem uma reinicialização completa do kernel para se recuperar).Em geral, se você deseja salvar o objeto traceback, é necessário limpá-lo das referências para
locals()
:No caso do notebook jupyter, você deve fazer isso pelo menos dentro do manipulador de exceções:
Testado com python 3.7.
O problema com o ambiente de notebook ipython ou jupyter é que ele possui
%tb
magia que salva o traceback e o disponibiliza a qualquer momento posteriormente. E, como resultadolocals()
, todos os quadros que participam do traceback não serão liberados até que o notebook saia ou outra exceção substituirá o backtrace armazenado anteriormente. Isso é muito problemático. Não deve armazenar o rastreio sem limpar seus quadros. Correção enviada aqui .fonte
O objeto pode ser usado como um parâmetro na
Exception.with_traceback()
função:fonte