我有类似的代码:
try:
if x:
statement1
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
statement7
在这里,我确信异常发生在If x:
块中,但我想知道If x:
阻止异常发生的哪个语句。有没有办法获得发生异常的行号?
此致
答案 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为基础......
使用系统错误而不是语句的优点是它们记录了更具体的信息,这有助于以后的调试(相信我得到了很多)
例如。我将它们记录到一个文本文件中,所以在我的程序在服务器上自动运行一夜之后,我可以检索任何问题,并有足够的信息来加快修复!
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