Обработка исключений Python - номер строки

Я использую python для оценки некоторых измеренных данных. Из-за многих возможных результатов трудно обрабатывать или возможные комбинации. Иногда во время оценки происходит ошибка. Обычно это ошибка индекса, потому что я получаю вне диапазона от измеренных данных.

Очень сложно выяснить, в каком месте в коде возникла проблема. Это очень помогло бы, если бы я знал, на какой строке была поднята ошибка. Если я использую следующий код:

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

К сожалению, это только говорит мне, что есть и ошибка индекса. Я хотел бы узнать более подробную информацию об исключении (строка в коде, переменной и т.д.), Чтобы узнать, что произошло. Возможно ли это?

Спасибо.

Ответ 1

Решение, печать имени файла, linenumber, самой строки и описания исключений:

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()

Вывод:

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

Ответ 2

Чтобы просто получить номер строки, вы можете использовать sys, если вы хотите получить больше, попробуйте модуль traceback.

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

печатает:

Error on line 3

Пример из документации модуля 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

Ответ 3

Самый простой способ - просто:

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

или при использовании ведения журнала:

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

Ответ 4

Я использую traceback которая проста и надежна:

import traceback

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

Из:

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

Ответ 5

Я бы предложил использовать библиотеку журналов python, в которой есть два полезных метода, которые могут помочь в этом случае.

  1. logging.findCaller()

    • findCaller (stack_info = False) - сообщает только номер строки для предыдущего вызывающего абонента, что приводит к возникновению исключения
    • findCaller (stack_info = True) - сообщает номер строки и стек для предыдущего вызывающего абонента, что приводит к возникновению исключения
  2. logging.logException()

    • Сообщает строку и стек в блоке try/Кроме того, что возникло исключение

Для получения дополнительной информации ознакомьтесь с API https://docs.python.org/3/library/logging.html