Программа для Python, которая отслеживает код вызова функции или реализации и хорошо выводит все это
Некоторые проекты настолько велики, что для понимания, например, вызова функции, вам необходимо пройти через множество различных блоков кода по всему проекту (например, в проектах с едва документированными API-интерфейсами). Много раз просто посмотреть на это не всегда достаточно, мне нужно часто записывать это, потому что вы должны смотреть назад и вперед между различными блоками кода.
Есть ли какая-либо программа, которая позволяет вам вставить функцию / метод или класс и получить полный отчет о трассировке для этого со всем кодом, который он вызывает? Также было бы удобно, если бы в то же время эта программа показывала вам структуру каталогов этого кода.
редактировать
====
Я уточнил свой вопрос в этой ветке стека. Я бы предпочел не запускать графический интерфейс для этого процесса каждый раз. Один вызов функции Python для получения результатов трассировки кажется лучшим решением.
3 ответа
Ответ на этот вопрос из этой ветки стека.
import trace
def trapy(arg):
tracer = trace.Trace()
tracer.run(arg)
r = tracer.results()
r.write_results()
if __name__ == '__main__':
import module_name
trapy('module_name.function_name()')
Возможно, вы ищете отладчик Python или версию графического интерфейса WinPDB, которая позволит вам следить за выполнением программы Python и правильно устанавливать точки останова (в __init__
класса, который вы хотите создать), вы сможете увидеть все следы, которые привели к созданию экземпляра.
В зависимости от того, на чем конкретно вы хотите сосредоточиться (только имена функций? Возвращаемые значения? Методы?), Вы можете реализовать разные вещи, просто используя sys.settrace
функция. Функция, которую вы передаете этому, будет вызываться для каждого выполнения, и вы можете настроить трассировку в соответствии с вашими потребностями. Ниже приведен пример, который я использую всякий раз, когда мне нужно понять поток новой программы / пакета.
Источник:
import sys, inspect
class Tracer(object):
def __init__(self):
self.tracing_packages = []
self.whitespace = ' '
self.indent_lvl = 0
def trace(self, frame, event, arg):
# Module info
mod = inspect.getmodule(frame)
if mod:
modpath = mod.__name__
else:
modpath = '<no module>'
# Just return if not interested in package
for to_trace in self.tracing_packages:
if not modpath.startswith(to_trace):
return self.trace
# Other info
fn_name = frame.f_code.co_name
src_lines = inspect.getsource(frame).split('\n')
src_line_start = src_lines[0]
src_line_end = src_lines[-1]
lineno = frame.f_lineno
ws = self.whitespace
# Printing
if event == 'call':
self.indent_lvl += 1
print('%scallin: %s %s %s' % (self.indent_lvl*ws, modpath, fn_name, str(arg)))
elif event == 'return':
if isinstance(arg, object):
ret = type(arg)
else:
ret = str(arg)
print('%sreturn: %s' % (self.indent_lvl*ws, ret))
self.indent_lvl -= 1
return self.trace
def watch_package(self, packname):
self.tracing_packages.append(packname)
пример
Здесь я просто хочу понять поток пакета под названием PyOCD:
>>> import sys, inspect, pyOCD
>>> tracer = Tracer()
>>> tracer.watch_package('pyOCD')
>>> sys.settrace(tracer.trace)
>>> pyOCD.board.MbedBoard.listConnectedBoards()
callin: pyOCD.board.mbed_board listConnectedBoards None
callin: pyOCD.board.mbed_board getAllConnectedBoards None
callin: pyOCD.interface.pyusb_backend getAllConnectedInterface
callin: pyOCD.interface.pyusb_backend __init__ None
callin: pyOCD.interface.interface __init__ None
return: <type 'NoneType'>
return: <type 'NoneType'>
callin: pyOCD.interface.pyusb_backend start_rx None
return: <type 'NoneType'>
return: <type 'list'>
...