Python的一个程序,它可以追溯函数调用或实例化的代码,并很好地打印出所有代码

2024-05-21 08:35:44 发布

您现在位置:Python中文网/ 问答频道 /正文

有些项目非常大,为了理解例如函数调用,需要在整个项目中遍历许多不同的代码块(例如,在几乎没有文档化api的项目中)。很多时候,仅仅看它并不总是足够的,我需要经常写下来,因为你需要在不同的代码块之间来回查看。你知道吗

是否有任何程序允许您插入一个函数/方法或类,并获得一个完整的回溯报告,以及它调用的所有代码?如果同时该程序向您展示该代码的目录结构,也会很方便。你知道吗

编辑

======

我在this stack thread中改进了我的问题。我不希望每次都为此进程启动gui。只需一个python函数调用就可以获得跟踪输出,这似乎是最好的解决方案。你知道吗


Tags: 项目方法函数代码文档程序目录api
3条回答

取决于你想关注什么(仅仅是函数名?返回值?方法?)您可以通过使用^{}函数来实现不同的功能。您传递给它的函数将在每次执行时被调用,您可以根据自己的需要定制一个回溯。下面我有一个例子,当我必须理解一个新程序/包的流程时,我会用到这个例子。你知道吗

来源:

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'>

            ...

也许您正在寻找python debugger,或者GUI版本WinPDB,它允许您跟踪python程序的执行,并且正确地设置了断点(在要实例化的类的__init__),您将能够看到导致实例化的所有回溯。你知道吗

这个问题的答案来自this stack thread。你知道吗

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()')

相关问题 更多 >