Определение номера строки, в которой возникает исключение в коде 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

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