有没有办法获取Python程序的跟踪表?或者一个程序运行另一个程序并获取其跟踪表?我是一名老师,试图完美地验证我们在测试中使用的跟踪问题的答案.
因此,例如,假设我有一个名为problem1.py以下内容的Python程序:
a = 1
b = 2
a = a + b
Run Code Online (Sandbox Code Playgroud)
执行推定的程序traceTable.py应该如下:
$ python traceTable.py problem1.py
L || a | b
1 || 1 |
2 || 1 | 2
4 || 3 | 2
Run Code Online (Sandbox Code Playgroud)
(或者使用不同语法的相同信息)
我查看了trace模块,我看不到它支持这个方法.
女士们,先生们:使用Ned Batchelder的优秀建议,我给你们traceTable.py!
好吧......差不多.正如您在Ned Batchelder的示例中所看到的,frame.f_lineno并不总是直观地表现(例如,第3行和第4行都被计为第4行),但行号足够接近以获得相当好的参考.此外,所有计算都是正确的.
我用一个包含if语句的长程序对它进行了测试,并给出了正确的表(没有行号).
您还会注意到,由于在他提到的大型程序中考虑了"更有趣的数据生态系统",我的程序比Ned Batchelder的概念验证要长得多.在使用范围execfile和管理它所需的所有变量以及降低噪声(ala ignored_variables)以及产生正确的字符串输出时,需要更多的代码:
'''
Usage: python traceTable.py program
-program Python program to be traced
'''
import sys
if len(sys.argv) < 2:
print __doc__
exit()
else:
file_name = sys.argv[1]
past_locals = {}
variable_list = []
table_content = ""
ignored_variables = set([
'file_name',
'trace',
'sys',
'past_locals',
'variable_list',
'table_content',
'getattr',
'name',
'self',
'object',
'consumed',
'data',
'ignored_variables'])
def trace(frame, event, arg_unused):
global past_locals, variable_list, table_content, ignored_variables
relevant_locals = {}
all_locals = frame.f_locals.copy()
for k,v in all_locals.items():
if not k.startswith("__") and k not in ignored_variables:
relevant_locals[k] = v
if len(relevant_locals) > 0 and past_locals != relevant_locals:
for i in relevant_locals:
if i not in past_locals:
variable_list.append(i)
table_content += str(frame.f_lineno) + " || "
for variable in variable_list:
table_content += str(relevant_locals[variable]) + " | "
table_content = table_content[:-2]
table_content += '\n'
past_locals = relevant_locals
return trace
sys.settrace(trace)
execfile(file_name)
table_header = "L || "
for variable in variable_list:
table_header += variable + ' | '
table_header = table_header[:-2]
print table_header
print table_content
Run Code Online (Sandbox Code Playgroud)
调用时,它会产生输出
$ python traceTable.py problem1.py
L || a | b
2 || 1
4 || 1 | 2
4 || 3 | 2
Run Code Online (Sandbox Code Playgroud)
Ned*_*der 10
这不是当前Python跟踪工具支持的用例,但应该可以构建.我不知道你如何决定输出哪些列.在您的示例中,a和b是唯一的局部变量,但较大的程序会有更有趣的数据生态系统.
更新:这是一个简单的概念证明:
1 import sys
2
3 def trace(frame, event, arg_unused):
4 print event, frame.f_lineno, frame.f_locals
5 return trace
6
7 sys.settrace(trace)
8
9 def foo():
10 a = 1
11 b = 2
12
13 a = a + b
14
15 foo()
Run Code Online (Sandbox Code Playgroud)
运行时,输出为:
call 9 {}
line 10 {}
line 11 {'a': 1}
line 13 {'a': 1, 'b': 2}
return 13 {'a': 3, 'b': 2}
Run Code Online (Sandbox Code Playgroud)