Есть ли способ получить таблицу трассировки для программы Python? Или для программы для запуска другой программы и получения ее таблицы трассировки? Я учитель, пытающийся безупречно проверить ответы на проблемы трассировки, которые мы используем в наших тестах.
Итак, например, если у меня есть программа Python с именем problem1.py
со следующим содержимым:
problem1.py
a = 1
b = 2
a = a + b
Выполнение предполагаемой программы traceTable.py
должно выглядеть следующим образом:
$ python traceTable.py problem1.py
L || a | b
1 || 1 |
2 || 1 | 2
4 || 3 | 2
(Или такая же информация с другим синтаксисом)
Я просмотрел модуль trace
, и я не вижу способа его поддержки.
Обновление
Дамы и господа: используя превосходный совет Нед Батчелдер, я даю вам traceTable.py
!
Ну.. почти. Как вы можете видеть в примере Ned Batchelder, frame.f_lineno
не всегда ведет себя интуитивно (например, обе строки 3 и 4 подсчитываются как строка 4), но номера строк достаточно близки для довольно хорошей ссылки. Кроме того, все вычисления верны.
Я тестировал это с помощью длинной программы, содержащей оператор if
, и он дал правильную таблицу (без номеров строк).
Вы также заметите, что моя программа значительно дольше, чем доказательство концепции Ned Batchelder из-за учета "более интересных экосистем данных" в более крупных программах, о которых он упомянул. В области использования execfile
и всех переменных, необходимых для управления им и уменьшения шума (ala ignored_variables
), а также для создания правильного вывода строки требуется намного больше кода:
traceTable.py
'''
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
При вызове он выдает вывод
$ python traceTable.py problem1.py
L || a | b
2 || 1
4 || 1 | 2
4 || 3 | 2