- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
看来 SyntaxError
s(和TypeError
s)由compile()
引发sys.exc_info()
返回的堆栈跟踪中未包含函数, 但被打印为使用 traceback.print_exc
的格式化输出的一部分.
例如,给定以下代码(其中 filename
是包含带有 $ flagrant syntax error
行的 Python 代码的文件的名称):
import sys
from traceback import extract_tb
try:
with open(filename) as f:
code = compile(f.read(), filename, "exec")
except:
print "using sys.exc_info:"
tb_list = extract_tb(sys.exc_info()[2])
for f in tb_list:
print f
print "using traceback.print_exc:"
from traceback import print_exc
print_exc()
我得到以下输出(其中 <scriptname>
是包含上述代码的脚本的名称):
using sys.exc_info:
('<scriptname>', 6, 'exec_file', 'code = compile(f.read(), filename, "exec")')
using traceback.print_exc:
Traceback (most recent call last):
File "<scriptname>", line 6, in exec_file
code = compile(f.read(), filename, "exec")
File "<filename>", line 3
$ flagrant syntax error
^
SyntaxError: invalid syntax
我有三个问题:
sys.exc_info()
追溯?包括 SyntaxError
所在的框架是生成的?traceback.print_exc
获取丢失的帧信息?SyntaxError
)的最佳方式是什么? ,在列表中?最后一个列表元素(即来自堆栈帧的信息表示 SyntaxError
发生的位置)是否需要使用 filename
手动构造?和 SyntaxError
异常对象本身?对于上下文,这是我尝试获取完整堆栈跟踪提取的用例。
我有一个程序,基本上通过 exec
实现 DSL正在处理一些包含用户编写的 Python 代码的文件。 (不管这是否是一个好的 DSL 实现策略,我或多或少都坚持使用它。)在用户代码中遇到错误时,我会(在某些情况下)希望解释器将错误保存为后来而不是呕吐堆栈跟踪和死亡。所以我有一个 ScriptExcInfo
专门用于存储此信息的类。这是该类的(略微编辑的版本)__init__
方法,针对上述问题完成了一个相当丑陋的解决方法:
def __init__(self, scriptpath, add_frame):
self.exc, tb = sys.exc_info()[1:]
self.tb_list = traceback.extract_tb(tb)
if add_frame:
# Note: I'm pretty sure that the names of the linenumber and
# message attributes are undocumented, and I don't think there's
# actually a good way to access them.
if isinstance(exc, TypeError):
lineno = -1
text = exc.message
else:
lineno = exc.lineno
text = exc.text
# '?' is used as the function name since there's no function context
# in which the SyntaxError or TypeError can occur.
self.tb_list.append((scriptpath, lineno, '?', text))
else:
# Pop off the frames related to this `exec` infrastructure.
# Note that there's no straightforward way to remove the unwanted
# frames for the above case where the desired frame was explicitly
# constructed and appended to tb_list, and in fact the resulting
# list is out of order (!!!!).
while scriptpath != self.tb_list[-1][0]:
self.tb_list.pop()
请注意,我所说的“相当丑陋”是指此解决方法将原本应该是单参数的 4 行 __init__
变成了一个变通方法。需要两个参数并占用 13 行的函数。
最佳答案
两种方法之间唯一的区别是print_exc()
打印格式化异常。对于包含格式化信息的 SyntaxError
,异常中包含导致问题的实际行。
对于回溯本身,print_exc()
使用 sys.exc_info()[2]
,您已经使用相同的信息来生成回溯。换句话说,它没有得到比你已经得到的更多的信息,但是你忽略了异常信息本身:
>>> import traceback
>>> try:
... compile('Hmmm, nope!', '<stdin>', 'exec')
... except SyntaxError as e:
... print ''.join(traceback.format_exception_only(type(e), e))
...
File "<stdin>", line 1
Hmmm, nope!
^
SyntaxError: invalid syntax
这里的traceback.format_exception_only()
是一个未记录的函数,被traceback.print_exc()
用来格式化异常值。所有信息都在那里供您提取异常本身:
>>> dir(e)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', 'args', 'filename', 'lineno', 'message', 'msg', 'offset', 'print_file_and_line', 'text']
>>> e.args
('invalid syntax', ('<stdin>', 1, 11, 'Hmmm, nope!\n'))
>>> e.filename, e.lineno, e.offset, e.text
('<stdin>', 1, 11, 'Hmmm, nope!\n')
另请参阅 traceback.print_exception()
的文档:
(3) if type is
SyntaxError
and value has the appropriate format, it prints the line where the syntax error occurred with a caret indicating the approximate position of the error.
Instances of this class have attributes
filename
,lineno
,offset
andtext
for easier access to the details.str()
of the exception instance returns only the message.
语法错误的行不包含在回溯中是合乎逻辑的;语法错误的代码无法执行,因此没有为它创建执行框架。异常是由最底层的执行框架 compile()
函数抛出的。
因此,您坚持使用“丑陋”的方法;这是处理 SyntaxError
异常的正确方法。但是,属性是记录的。
请注意,exception.message
通常设置为 exception.args[0]
,而 str(exception)
通常 给你相同的消息(如果 args
更长你得到 str(exception.args)
而不是,尽管一些异常类型提供自定义 __str__
通常只会给你 exception.args[0]
)。
关于python - 从 compile() 获取包括 SyntaxError 在内的回溯信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27364868/
我在 Python 2 中尝试了这段代码: def NewFunction(): return '£' 但我收到一条错误消息: SyntaxError: Non-ASCII character
我正在学习xpath,并且我正尝试从html usint xpath获取一些数据 我发现谷歌浏览器可以选择“复制xpath”,效果很好 但不适用于这个例子 some divs
我是 ruby 的初学者。我想修复其中一个邮件软件中的错误。我应用的修复代码如下: @headers[:recipient] = { "To" => (cc.map do |p|
我是初学者级别的python用户,当我在终端中键入以下内容时: $ pydoc Inleesgenbank.py 我收到以下错误消息: ./Inleesgenbank.py中的问题-:语法无效(Inl
我正在编写用于解析电子邮件的脚本,但是以下部分的for循环上有一些SyntaxError: def main(): writer = csv.DictWriter(open('feature
我正在尝试在python33中创建分发文件,但没有成功。 我用嵌套器名称创建了一个文件夹,并在Windows 8的C驱动程序中放入了python33。 此文件夹有2个文件。 nester.py和set
当我尝试导入NumPy时,突然出现以下错误: 更具体地说,它在我键入时显示: import numpy as np 要不就: import numpy 它也会在Python控制台中发生,如下所示: P
在我的 HTML 文件中,我有一行(如下)通过 WiFi 从设备获取响应并使数据可用于我的 JavaScript,它运行良好,除非响应文本中有错误并停止。 响应是一个代表 JavaScript 变量的
我开始使用 Javascript OOP,我编写了我的第一个类,但我在控制台中收到消息错误 这是类(class): class Quote{ deleteQuote(callback){ $(
我正在使用argparse来解析参数,但是当我得到args.global时,出现了一个奇怪的错误,我不知道我哪里做错了 ... parser.add_argument('-u','--update',
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我正在使用argparse来解析参数,但是当我得到args.global时,出现了一个奇怪的错误,我不知道我哪里做错了 ... parser.add_argument('-u','--update',
有什么不同?为什么它会在函数 a() 中出错? function a(){ 1 == 1 ? return true: ""; // Uncaught SyntaxError: Unexpe
我有一个 python 脚本,其中包含如下函数参数的类型声明: def dump_var(v: Variable, name: str = None): 据我所知,这是一个为函数设置输入参数类型的有效
我正在尝试从命令行运行 Python 脚本,这是我的脚本: import sys def printsomething(sys.argv): text = str(sys.argv[1])
我在 macbook 上使用终端将数据打印到打开的文件中: >>> out=open("test_output.txt","w") >>> print("hello",file=out) File
我想排除以下代码产生的错误,但我不知道如何。 from datetime import datetime try: date = datetime(2009, 12a, 31) except:
我想在动态生成的列表中放置一个 onclick 事件。我不能按原样使用它,例如 updateRoomID(arg) ,因为它会立即开火。所以我把它放在一个匿名函数中,按照网上各种来源的建议:funct
我有以下脚本: 测试.py: import sys try: import random print random.random() except: print sys.exc
这个问题在这里已经有了答案: "+=" causing SyntaxError in Python (6 个答案) 关闭 3 年前。 在我的代码中有这些行: if numVotes == 0:
我是一名优秀的程序员,十分优秀!