假设我使用compile从字符串和名称创建code
对象:
>>> a = compile('raise ValueError\n', '<at runtime>', 'exec')
我希望该字符串中的行显示在回溯中(注意 - 以下内容在IDLE中运行):
>>> exec(a)
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
exec(c)
File "<at runtime>", line 1, in <module>
raise ValueError <-- This line is what I want
ValueError
唉,他们没有:
>>> exec(a)
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
exec(c)
File "<at runtime>", line 1, in <module>
ValueError
如果不创建临时文件,如何在追溯中显示raise ValueError
行?
答案 0 :(得分:3)
使用内置linecache
的未记录的cache
成员,这似乎有效:
def better_compile(src, name, mode):
# there is an example of this being set at
# https://hg.python.org/cpython/file/2.7/Lib/linecache.py#l104
from linecache import cache
cache[name] = (
len(src), None,
[line+'\n' for line in src.splitlines()], name
)
return compile(src, name, mode)
>>> c = better_compile('raise ValueError\n', '<a name>', 'exec')
>>> exec(c)
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
exec(c)
File "<a name>", line 1, in <module>
raise ValueError
ValueError
答案 1 :(得分:0)
好吧,你可以编写自己的异常处理程序来填充数据:
code = """
def f1():
f2()
def f2():
1 / 0
f1()
"""
a = compile(code, '<at runtime>', 'exec')
import sys
import traceback
try:
exec(a)
except:
etype, exc, tb = sys.exc_info()
exttb = traceback.extract_tb(tb)
## Fill the missing data:
exttb2 = [(fn, lnnr, funcname,
(code.splitlines()[lnnr-1] if fn=='<at runtime>'
else line))
for fn, lnnr, funcname, line in exttb]
# Print:
sys.stderr.write('Traceback (most recent call last):\n')
for line in traceback.format_list(exttb2):
sys.stderr.write(line)
for line in traceback.format_exception_only(etype, exc):
sys.stderr.write(line)
结果:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<at runtime>", line 8, in <module>
f1()
File "<at runtime>", line 3, in f1
f2()
File "<at runtime>", line 6, in f2
1 / 0
ZeroDivisionError: integer division or modulo by zero
现在只需打包编译&amp;执行smart_exec
函数每次调用...