Я хочу отслеживать строки скрипта Python по мере их выполнения. Однако программа, которую я использую, должна выводить данные на стандартный вывод. Параметр трассировки модуля трассировки python выводит их на стандартный вывод. Можно ли сказать, чтобы он не печатал их в стандартный вывод, а вместо этого сохранял в файл? Я пробовал установить параметр outfile
, но он не останавливает печать линий трассировки.
Модуль трассировки Python - отслеживает строки по мере их выполнения, но сохраняет в файл, а не в стандартный вывод.
Ответы (5)
Вы можете скопировать код модуля трассировки и внести несколько изменений, чтобы заставить его записывать выходные данные в файл по вашему выбору. Между строками 600 и 650 есть пять операторов print
, которые вы хотите изменить. Поскольку вам не нужно делать его слишком красивым, вы можете добавить это в самый конец файла:
my_out_file = open("/home/mytrace.txt", "w")
и измените операторы печати так:
print "%s(%d): %s" % (bname, lineno,
linecache.getline(filename, lineno)),
становится это:
print >>my_out_file, "%s(%d): %s" % (bname, lineno,
linecache.getline(filename, lineno)),
open(..., buffering=1)
- person ti7; 18.06.2021
Согласно документации модуля трассировки, выходной файл используется только для записи обновленной информации о счетчике.
Модуль трассировки продолжит вывод информации трассировки на стандартный вывод.
Для ручной трассировки, если есть функция входа, я использовал sys.settrace для выполнения работы по отслеживанию потоков вызовов. Его можно расширить, чтобы отслеживать выполнение построчно. Вы всегда можете записать информацию в файл, а не печатать ее на стандартный вывод.
Простая структура - это
import sys
import os
import linecache
trace_depth = 0
def trace(f):
def globaltrace(frame, why, arg):
global trace_depth
if why == "call":
# function call event , extract information
.....
pass
trace_depth = trace_depth + 1
return None
def localtrace(frame, why, arg):
global trace_depth
if why == "line":
# line execution event
pass
elif why == "return":
trace_depth = trace_depth - 1
# function return event
return localtrace
def _f(*args, **kwds):
sys.settrace(globaltrace)
result = f(*args, **kwds)
sys.settrace(None)
return result
return _f
globaltrace и localtrace - это функции обратного вызова, которые вызываются с событием "почему".
скажем, для события, когда вызывается функция, вы можете извлечь информацию из деталей кадра.
if why == "call":
# Parent frame details
p_func = frame.f_back.f_code.co_name
p_file = frame.f_back.f_code.co_filename
p_lineinfo = frame.f_back.f_lineno
Полную информацию я опубликовал здесь.
Может случиться так, что вам понадобится так называемая «трассировка функции», описанная для PHP. Я создал инструмент Python, который производит аналогичный вывод с использованием хука pyfunc sys.settrace ().
Вы вызываете трассировку в командной строке? Если это так, я рекомендую использовать стандартный метод перенаправления любого stdout в любой файл. Перенаправить весь вывод в файл
foo > allout.txt 2>&1
Я уверен, что в Windows есть что-то подобное, если вы находитесь в Windows.
Другая возможность, когда вы используете stdout / stderr для чего-то еще, - это запустить поток для записи и отправки сообщений в очередь
import threading
from queue import Queue
def worker(Q, file_dest):
with open(file_dest, "r+", buffering=1) as fh:
while True:
fh.write(f"{}\n".format(Q.get()))
...
dest_file = "some-writeable/path.txt"
Q = Queue() # can be a global, but please name it better!
t = threading.Thread(
worker,
args=(Q, dest_file),
daemon=True, # don't block exit
)
# set t.daemon = True here instead in earlier Python
t.start()
всякий раз, когда вы хотите написать, используйте метод .put()
Q.put("some message")
buffering=1
используется для буферизации строк