定位Python代码中异常发生的行号
我有一段代码,类似于这个:
try:
if x:
statement1
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
statement7
在这里,我确定异常发生在 If x:
这个块里,但我想知道在 If x:
这个块中的哪一行出现了异常。有没有办法找到异常发生的行号呢?
谢谢,
10 个回答
4
你应该在调试器中运行你的程序,比如说 pdb
。这样的话,当你的代码出现意外情况时,你可以正常运行代码,然后检查一下当时的环境。
假设你有一个叫做 'main.py' 的脚本,你可以这样运行它:
python -m pdb main.py
然后,当你的程序启动时,它会在调试器中开始运行。你可以输入 c
来继续执行,直到下一个断点(或者崩溃)。接着,你可以通过输入像 print spam.eggs
这样的命令来检查环境。你还可以通过输入 pdb.set_trace()
来设置断点(我通常会写 import pdb; pdb.set_trace()
)。
另外,你说 'statement 3' 抛出异常是“可以的”,这是什么意思呢?你是期待这个异常吗?如果是这样的话,可能更好的是在这个语句周围写一个 try/except 块,这样程序就可以继续运行了。
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
更新版本的 traceback 处理修复了 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)
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