web-dev-qa-db-fra.com

Python gestion des exceptions - numéro de ligne

J'utilise python pour évaluer certaines données mesurées. En raison de nombreux résultats possibles, il est difficile à gérer ou des combinaisons possibles. Parfois, une erreur se produit pendant l'évaluation. Il s'agit généralement d'une erreur d'indexation car je sortir de la plage des données mesurées.

Il est très difficile de savoir à quel endroit du code le problème s'est produit. Cela aiderait beaucoup si je savais sur quelle ligne l'erreur a été soulevée. Si j'utilise le code suivant:

try:
    result = evaluateData(data)
except Exception, err:
    print ("Error: %s.\n" % str(err))

Malheureusement, cela me dit seulement qu'il y a une erreur d'indexation. J'aimerais en savoir plus sur l'exception (ligne de code, variable etc.) pour savoir ce qui s'est passé. C'est possible?

Merci.

46
JeCh

Solution, nom du fichier d'impression, numéro de lin, ligne elle-même et description d'exception:

import linecache
import sys

def PrintException():
    exc_type, exc_obj, tb = sys.exc_info()
    f = tb.tb_frame
    lineno = tb.tb_lineno
    filename = f.f_code.co_filename
    linecache.checkcache(filename)
    line = linecache.getline(filename, lineno, f.f_globals)
    print 'EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj)


try:
    print 1/0
except:
    PrintException()

Sortie:

EXCEPTION IN (D:/Projects/delme3.py, LINE 15 "print 1/0"): integer division or modulo by zero
67
Apogentus

Pour obtenir simplement le numéro de ligne, vous pouvez utiliser sys, si vous souhaitez en avoir plus, essayez le module traceback .

import sys    
try:
    [][2]
except IndexError:
    print 'Error on line {}'.format(sys.exc_info()[-1].tb_lineno)

imprime :

Error on line 3

Exemple de la documentation du module traceback :

import sys, traceback

def lumberjack():
    bright_side_of_death()

def bright_side_of_death():
    return Tuple()[0]

try:
    lumberjack()
except IndexError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print "*** print_tb:"
    traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
    print "*** print_exception:"
    traceback.print_exception(exc_type, exc_value, exc_traceback,
                              limit=2, file=sys.stdout)
    print "*** print_exc:"
    traceback.print_exc()
    print "*** format_exc, first and last line:"
    formatted_lines = traceback.format_exc().splitlines()
    print formatted_lines[0]
    print formatted_lines[-1]
    print "*** format_exception:"
    print repr(traceback.format_exception(exc_type, exc_value,
                                          exc_traceback))
    print "*** extract_tb:"
    print repr(traceback.extract_tb(exc_traceback))
    print "*** format_tb:"
    print repr(traceback.format_tb(exc_traceback))
    print "*** tb_lineno:", exc_traceback.tb_lineno
23
root

Le moyen le plus simple consiste simplement à utiliser:

import traceback
try:
    <blah>
except IndexError:
    traceback.print_exc()

ou si vous utilisez la journalisation:

import logging
try:
    <blah>
except IndexError as e:
    logging.exception(e)
8
acowpy

J'utilise le traceback qui est simple et robuste:

import traceback

try:
    raise ValueError()
except:
    print(traceback.format_exc())

En dehors:

Traceback (most recent call last):
  File "catch.py", line 4, in <module>
    raise ValueError()
ValueError
4
Benyamin Jafari

Je suggère d'utiliser la bibliothèque de journalisation python, elle a deux méthodes utiles qui pourraient aider dans ce cas.

  1. logging.findCaller ()

    • findCaller (stack_info = False) - Indique uniquement le numéro de ligne de l'appelant précédent menant à l'exception levée
    • findCaller (stack_info = True) - Indique le numéro de ligne et la pile de l'appelant précédent menant à l'exception levée
  2. logging.logException ()

    • Signale la ligne et la pile dans le bloc try/except qui ont déclenché l'exception

Pour plus d'informations, consultez l'API https://docs.python.org/3/library/logging.html

0
grandma