如何从 Python 中的 exec 或 execfile 获取错误的行号 [英] how to get the line number of an error from exec or execfile in Python

查看:37
本文介绍了如何从 Python 中的 exec 或 execfile 获取错误的行号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下多行字符串:

cmd = """一 = 1 + 1乙 = [2 + 2,4 + 4,]博克博克博克"""

并且我想在特定范围内执行它:

scope = {}exec( cmd, 作用域)打印范围['b']

在命令的第 6 行有一个 SyntaxError,我希望能够将其报告给用户.我如何获得行号?我试过这个:

尝试:exec( cmd, scope ) # <-- 假设这是在源文件的第 123 行除了异常,错误:a, b, c = sys.exc_info()line_number = c.tb_lineno # <-- 这让我得到 123,而不是 6打印%s 在第 %d (%s) 行" % ( a, line_number, b.message )

...但我得到的是 exec 语句的行号,而不是多行命令中的行号.

更新:事实证明,我在本示例中任意选择的异常类型 SyntaxError 的处理与任何其他类型的处理不同.澄清一下,我正在寻找一种可以应对任何类型异常的解决方案.

解决方案

对于语法错误,源行号可用作异常对象本身的 lineno 标志,在您的情况下存储在 <代码>错误.这是特定于行号是错误的组成部分的语法错误:

<预><代码>>>>cmd = """... 1 \ +... 2 *"……">>>尝试:... 执行命令... 除了 SyntaxError 作为错误:... 打印 err.lineno...2

如果还想处理其他错误,添加一个新的exceptexcept Exception, err,并使用traceback模块进行计算运行时错误的行号.

导入系统导入回溯类解释器错误(异常):通过def my_exec(cmd, globals=None, locals=None, description='source string'):尝试:exec(cmd,全局变量,本地变量)除了 SyntaxError 作为错误:error_class = err.__class__.__name__详细信息 = err.args[0]line_number = err.lineno除了作为错误的异常:error_class = err.__class__.__name__详细信息 = err.args[0]cl, exc, tb = sys.exc_info()line_number = traceback.extract_tb(tb)[-1][1]别的:返回raise InterpreterError("%s at line %d of %s: %s" % (error_class, line_number, description, detail))

示例:

<预><代码>>>>my_exec("1+1") # 也不例外>>>>>>my_exec("1+1\nbork")...InterpreterError: NameError at line 2 of source string: name 'bork' is not defined>>>>>>my_exec("1+1\nbork bork")...InterpreterError: SyntaxError at line 2 of source string: invalid syntax>>>>>>my_exec("1+1\n'''")...解释器错误:源字符串第 2 行处的语法错误:扫描三重引号字符串时的 EOF

Let's say I have the following multi-line string:

cmd = """
    a = 1 + 1
    b = [
       2 + 2,
       4 + 4,
    ]
    bork bork bork
"""

and I want to execute it in a particular scope:

scope = {}
exec( cmd, scope )
print scope[ 'b' ]

There's a SyntaxError at line 6 of the command, and I want to be able to report that to the user. How do I get the line number? I've tried this:

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 )

...but I get the line number of the exec statement, not the line number within the multi-line command.

Update: it turns out the handling of the type of exception that I arbitrarily chose for this example, the SyntaxError, is different from the handling of any other type. To clarify, I'm looking a solution that copes with any kind of exception.

解决方案

For syntax errors, the source line number is available as the lineno flag on the exception object itself, in your case stored in err. This is specific to syntax errors where the line number is an integral part of the error:

>>> cmd = """
... 1 \ +
... 2 * "
... """
>>> try:
...   exec cmd
... except SyntaxError as err:
...   print err.lineno
... 
2

If you want to also handle other errors, add a new except block except Exception, err, and use the traceback module to compute the line number for the runtime error.

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

Examples:

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

这篇关于如何从 Python 中的 exec 或 execfile 获取错误的行号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆