繁体   English   中英

定位python代码中发生异常的行号

[英]Locating the line number where an exception occurs in python code

我有一个类似的代码:

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

except:
      statement7

在这里,我相信所发生的例外If x:块,但我想知道其中的发言If x:阻止出现异常。 有没有办法获取发生异常的行号?

问候,

那这个呢:

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

我相信这里建议您更严格地管理try/except块的几个答案是您正在寻找的答案。 那是一种风格,而不是图书馆的东西。

然而,有时我们发现自己在一个情况下它不是一种风格的东西,你真的需要行号做一些其他programattic行动。 如果这就是您要问的,您应该考虑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)

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

给定一个名为“main.py”的脚本,像这样运行它:

python -m pdb main.py

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

此外,“语句 3”引发异常是什么意思? 你期待例外吗? 如果是这样,最好在此语句周围编写一个 try/except 块,以便程序可以继续。

我以前做过以下工作:

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

 except:
    print "exception occurred doing ", doing

打印检查点的优点是没有日志输出,除非确实有异常。

建立在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
>>>

您应该更紧密地包装您关心的语句。 从回溯中提取行号将涉及且脆弱。

如果你像这样重构代码,当再次引发异常时你应该得到一个行号:

except:
    statement7
    raise

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

此外,您应该用 try except 结构化应该引发异常的代码位。

我们可以通过拆分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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM