簡體   English   中英

如何從Python中的exec或execfile獲取錯誤的行號

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM