在python代码中找到发生异常的行号

时间:2011-08-05 19:40:58

标签: python exception

我有类似的代码:

try:
  if x:
      statement1
      statement2
      statement3
  elif y:
      statement4
      statement5
      statement6
  else:
      raise

except:
      statement7

在这里,我确信异常发生在If x:块中,但我想知道If x:阻止异常发生的哪个语句。有没有办法获得发生异常的行号?

此致

10 个答案:

答案 0 :(得分:21)

怎么样:

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

答案 1 :(得分:13)

我相信这里的几个答案建议您更紧密地管理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)

答案 2 :(得分:4)

您应该在调试器中运行程序,例如pdb。这将允许您正常运行代码,然后在出现意外情况时检查环境。

给定一个名为'main.py'的脚本,运行如下:

python -m pdb main.py

然后,当您的程序启动时,它将在调试器中启动。键入c以继续下一个断点(或崩溃)。然后,您可以通过执行print spam.eggs之类的操作来检查环境。您还可以通过执行pdb.set_trace()(我通常import pdb; pdb.set_trace())来设置断点。

另外,你的意思是“声明3”提出异常是“好吗”?你期待例外吗?如果是这样,最好在这个语句周围写一个try / except块,这样程序就可以继续了。

答案 3 :(得分:3)

之前我做过以下事情:

try:
    doing = "statement1"
    statement1
    doing = "statement2"
    statement2
    doing = "statement3"
    statement3
    doing = "statement4"
    statement4

 except:
    print "exception occurred doing ", doing

打印检查点的优势是没有日志输出,除非  实际上有一个例外。

答案 4 :(得分:3)

以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
>>>

答案 5 :(得分:2)

你应该更紧密地包装你关心的陈述。从回溯中提取行号将涉及且易碎。

答案 6 :(得分:2)

如果像这样重构代码,则应在再次引发异常时获取行号:

except:
    statement7
    raise

答案 7 :(得分:1)

使用一般的except语句通常是一种糟糕的编程习惯,因此您应该在except语句中指定要捕获的异常。 (比如ValueError:)

此外,你应该尝试一下,除了构造应该引发异常的代码位。

答案 8 :(得分:0)

编辑您的源代码,以便一次删除一行,直到错误消失,这应该指向您更接近问题。

答案 9 :(得分:0)

我们可以通过分割traceback.format_exc()的字符串状态来获取行号。 请尝试运行以下代码。

import traceback

try:
    a = "str"
    b = 10

    c = a + b
except Exception as e:
    err_lineno = str(traceback.format_exc()).split(",")[1]
    print(err_lineno)

这将产生以下输出

line 7