Обработка исключений 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, в которой есть два полезных метода, которые могут помочь в этом случае.
-
logging.findCaller()
- findCaller (stack_info = False) - сообщает только номер строки для предыдущего вызывающего абонента, что приводит к возникновению исключения
- findCaller (stack_info = True) - сообщает номер строки и стек для предыдущего вызывающего абонента, что приводит к возникновению исключения
-
logging.logException()
- Сообщает строку и стек в блоке try/Кроме того, что возникло исключение
Для получения дополнительной информации ознакомьтесь с API https://docs.python.org/3/library/logging.html