Je souhaite enregistrer le nom de l'erreur et les détails du retraçage dans une variable. Voici ma tentative.
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]
Production:
0 <type 'exceptions.NameError'>
1
2 <traceback object at 0xbd5fc8>
Sortie désirée:
0 NameError
1
2 Traceback (most recent call last):
File "exception.py", line 6, in <module>
raise NameError
PS Je sais que cela peut être fait facilement en utilisant le module de traceback, mais je veux connaître l'utilisation de l'objet sys.exc_info () [2] ici.
python
exception-handling
codeurs du noir
la source
la source
<python install path>/Lib/traceback.py
) pour plus d'informations.Réponses:
Voici comment je fais:
Vous devriez cependant jeter un œil à la documentation de traceback , car vous y trouverez peut-être des méthodes plus appropriées, en fonction de la façon dont vous souhaitez traiter votre variable par la suite ...
la source
sys.exc_info()[2].tb_frame.f_code.co_names[3]
, mais cela n'a aucun sens ... S'il y a un module appelétraceback
dans la bibliothèque standard, il y a une raison à cela ... :)traceback.format_exception(*sys.exc_info())
est le moyen de le faire. Mais c'est fonctionnellement équivalent àtraceback.format_exc()
.sys.exc_info () retourne un tuple avec trois valeurs (type, valeur, traceback).
Par exemple, dans le programme suivant
Maintenant, si nous imprimons le tuple, les valeurs seront les suivantes.
Les détails ci-dessus peuvent également être récupérés en imprimant simplement l'exception au format chaîne.
la source
À utiliser
traceback.extract_stack()
si vous souhaitez un accès pratique aux noms de module et de fonction et aux numéros de ligne.À utiliser
''.join(traceback.format_stack())
si vous voulez juste une chaîne qui ressemble à latraceback.print_stack()
sortie.Notez que même avec
''.join()
vous obtiendrez une chaîne multiligne, puisque les éléments deformat_stack()
contiennent\n
. Voir la sortie ci-dessous.N'oubliez pas
import traceback
.Voici la sortie de
traceback.extract_stack()
. Mise en forme ajoutée pour la lisibilité.Voici la sortie de
''.join(traceback.format_stack())
. Mise en forme ajoutée pour la lisibilité.la source
Soyez prudent lorsque vous retirez l'objet d'exception ou l'objet de trace du gestionnaire d'exceptions, car cela provoque des références circulaires et
gc.collect()
échouera à collecter. Cela semble être un problème particulier dans l'environnement du notebook ipython / jupyter où l'objet de trace n'est pas effacé au bon moment et même un appel explicite àgc.collect()
infinally
section ne fait rien. Et c'est un énorme problème si vous avez des objets énormes qui ne récupèrent pas leur mémoire à cause de cela (par exemple, les exceptions de mémoire insuffisante de CUDA qui sans cette solution nécessitent un redémarrage complet du noyau pour récupérer).En général, si vous souhaitez enregistrer l'objet de trace, vous devez le supprimer des références à
locals()
, comme ceci:Dans le cas du notebook jupyter, vous devez au moins le faire dans le gestionnaire d'exceptions:
Testé avec python 3.7.
ps le problème avec ipython ou jupyter notebook env est qu'il a de la
%tb
magie qui enregistre le traçage et le rend disponible à tout moment plus tard. Et par conséquent, touteslocals()
les trames participant au suivi ne seront pas libérées jusqu'à ce que le bloc-notes se termine ou qu'une autre exception écrase la trace arrière précédemment stockée. C'est très problématique. Il ne doit pas stocker la trace sans nettoyer ses cadres. Correctif soumis ici .la source
L'objet peut être utilisé comme paramètre en
Exception.with_traceback()
fonction:la source