Программа для 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'>

            ...
Другие вопросы по тегам