Определение номера строки, в которой возникает исключение в коде python
У меня есть код, похожий на этот:
try:
if x:
statement1
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
statement7
Здесь я уверен, что исключение происходит в блоке If x:
, но я хотел бы знать, в чем состоит выражение If x:
блокировать исключение. Есть ли способ получить номер строки, где происходит исключение?
Привет,
Ответы
Ответ 1
что об этом:
try:
if x:
print 'before statement 1'
statement1
print 'before statement 2' #ecc. ecc.
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
statement7
это простой способ обхода, но я предлагаю использовать отладчик
или даже лучше, используйте модуль sys: D
try:
if x:
print 'before statement 1'
statement1
print 'before statement 2' #ecc. ecc.
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
print sys.exc_traceback.tb_lineno
#this is the line number, but there are also other infos
Ответ 2
Я считаю, что несколько ответов здесь рекомендуют вам более эффективно управлять блоками try/except
- это ответ, который вы ищете. Это вещь стиля, а не вещь в библиотеке.
Однако время от времени мы оказываемся в ситуации, когда это не стиль, и вам действительно нужен номер строки для выполнения некоторых других программных действий. Если это то, о чем вы просите, вы должны рассмотреть модуль traceback
. Вы можете извлечь всю необходимую информацию о последнем исключении. Функция tb_lineno
вернет номер строки, вызывающий исключение.
>>> import traceback
>>> dir(traceback)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_format_final_exc_line', '_print', '_some_str', 'extract_stack', 'extract_tb', 'format_exc', 'format_exception', 'format_exception_only', 'format_list', 'format_stack', 'format_tb', 'linecache', 'print_exc', 'print_exception', 'print_last', 'print_list', 'print_stack', 'print_tb', 'sys', 'tb_lineno', 'types']
>>> help(traceback.tb_lineno)
Help on function tb_lineno in module traceback:
tb_lineno(tb)
Calculate correct line number of traceback given in tb.
Obsolete in 2.3
Более новые версии трассировки трассировки исправляют проблему до 2.3, позволяя нижеприведенному коду работать так, как планировалось: (это "правильный путь" )
import traceback
import sys
try:
raise Exception("foo")
except:
for frame in traceback.extract_tb(sys.exc_info()[2]):
fname,lineno,fn,text = frame
print "Error in %s on line %d" % (fname, lineno)
Ответ 3
Вы должны запустить свою программу в отладчике, например pdb
. Это позволит вам нормально запускать ваш код, а затем изучить среду, когда произойдет что-то неожиданное.
Учитывая script с именем 'main.py', запустите его следующим образом:
python -m pdb main.py
Затем, когда ваша программа запустится, она начнется в отладчике. Введите c
для продолжения до следующей точки останова (или сбоя). Затем вы можете изучить среду, выполнив такие действия, как print spam.eggs
. Вы также можете установить точки останова, выполнив pdb.set_trace()
(обычно я делаю import pdb; pdb.set_trace()
).
Кроме того, что вы имеете в виду, что это "нормально" для "утверждения 3", чтобы поднять исключение? Вы ожидаете исключения? Если это так, возможно, лучше написать блок try/except вокруг этого оператора, чтобы программа могла продолжить.
Ответ 4
Я уже делал следующее:
try:
doing = "statement1"
statement1
doing = "statement2"
statement2
doing = "statement3"
statement3
doing = "statement4"
statement4
except:
print "exception occurred doing ", doing
Преимущество над контрольно-пропускными пунктами для печати - отсутствие выхода журнала, кроме
на самом деле существует исключение.
Ответ 5
Основываясь на JJ выше..
Преимущество использования системных ошибок над операторами заключается в том, что они записывают более конкретную информацию, которая позже поможет в отладке (верьте, что я получаю много)
например. Я записываю их в текстовый файл, поэтому после того, как мои программы автоматически запускаются на ночь на сервере, я могу получить любые проблемы и получить достаточно информации, чтобы ускорить восстановление!
Подробнее... Traceback и Sys
import traceback
import sys
try:
print 1/0
except Exception as e:
print '1', e.__doc__
print '2', sys.exc_info()
print '3', sys.exc_info()[0]
print '4', sys.exc_info()[1]
print '5', sys.exc_info()[2], 'Sorry I mean line...',traceback.tb_lineno(sys.exc_info()[2])
ex_type, ex, tb = sys.exc_info()
print '6', traceback.print_tb(tb)
Урожайность
> 1 Second argument to a division or modulo operation was zero.
> 2 (<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division
> or modulo by zero',), <traceback object at 0x022DCF30>)
> 3 <type 'exceptions.ZeroDivisionError'>
> 4 integer division or modulo by zero
> 5 <traceback object at 0x022DCF30> Sorry I mean line... 5
> 6 File "Z:\Programming\Python 2.7\Error.py", line 5, in <module>
> print 1/0
None
>>>
Ответ 6
Вы должны более внимательно обернуть заявления, о которых вы заботитесь. Извлечение номера строки из трассировки будет задействовано и хрупко.
Ответ 7
Если вы реструктурируете такой код, вы должны получить номер строки, когда исключение снова будет создано:
except:
statement7
raise
Ответ 8
Использование общей инструкции except обычно является плохой практикой программирования, поэтому вы должны указать в своем исключении, какое исключение вы хотите поймать. (например, за исключением ValueError:)
Кроме того, вы должны окружить с помощью try, кроме структуры, биты кода, которые должны создавать исключение.
Ответ 9
Отредактируйте исходный код, чтобы удалить одну строку за раз, пока ошибка не исчезнет, и это должно указывать на то, что вы ближе к проблеме.