[英]how to get the line number of an error from exec or execfile in Python
假设我有以下多行字符串:
cmd = """
a = 1 + 1
b = [
2 + 2,
4 + 4,
]
bork bork bork
"""
我想在特定范围内执行它:
scope = {}
exec( cmd, scope )
print scope[ 'b' ]
在命令的第6行有一个SyntaxError
,我希望能够向用户报告。 我如何获得行号? 我试过这个:
try:
exec( cmd, scope ) # <-- let's say this is on line 123 of the source file
except Exception, err:
a, b, c = sys.exc_info()
line_number = c.tb_lineno # <-- this gets me 123, not 6
print "%s at line %d (%s)" % ( a, line_number, b.message )
...但是我得到了exec
语句的行号,而不是多行命令中的行号。
更新:事实证明,我为此示例任意选择的异常类型的处理, SyntaxError
,与处理任何其他类型不同。 为了澄清,我正在寻找一种能够应对任何异常的解决方案。
对于语法错误,源行号可用作异常对象本身的lineno
标志,在您的情况下存储在err
。 这特定于语法错误,其中行号是错误的组成部分:
>>> cmd = """
... 1 \ +
... 2 * "
... """
>>> try:
... exec cmd
... except SyntaxError as err:
... print err.lineno
...
2
如果还要处理其他错误,请添加except Exception, err
的新except
块,并使用traceback
模块计算运行时错误的行号。
import sys
import traceback
class InterpreterError(Exception): pass
def my_exec(cmd, globals=None, locals=None, description='source string'):
try:
exec(cmd, globals, locals)
except SyntaxError as err:
error_class = err.__class__.__name__
detail = err.args[0]
line_number = err.lineno
except Exception as err:
error_class = err.__class__.__name__
detail = err.args[0]
cl, exc, tb = sys.exc_info()
line_number = traceback.extract_tb(tb)[-1][1]
else:
return
raise InterpreterError("%s at line %d of %s: %s" % (error_class, line_number, description, detail))
例子:
>>> my_exec("1+1") # no exception
>>>
>>> my_exec("1+1\nbork")
...
InterpreterError: NameError at line 2 of source string: name 'bork' is not defined
>>>
>>> my_exec("1+1\nbork bork bork")
...
InterpreterError: SyntaxError at line 2 of source string: invalid syntax
>>>
>>> my_exec("1+1\n'''")
...
InterpreterError: SyntaxError at line 2 of source string: EOF while scanning triple-quoted string
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.