2

一部のプロジェクトは非常に大きいため、たとえば関数呼び出しを理解するために、プロジェクト全体でさまざまなコード ブロックを確認する必要があります (たとえば、ドキュメント化された API がほとんどないプロジェクトなど)。多くの場合、ただ見るだけでは十分ではありません。さまざまなコード ブロック間を行き来する必要があるため、頻繁に書き留める必要があります。

関数/メソッドまたはクラスを挿入し、それが呼び出すすべてのコードを含む完全なトレースバック レポートを取得できるプログラムはありますか? また、そのプログラムが同時にそのコードのディレクトリ構造を示していれば便利です。

編集

====

このスタック スレッドで質問を絞り込みました。このプロセスのたびに GUI を起動したくありません。トレース出力を取得するための 1 つの Python 関数呼び出しが最適なソリューションのようです。

4

3 に答える 3

2

この質問への答えは、このスタックスレッドからです。

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()')
于 2012-06-20T12:47:52.400 に答える
1

何に焦点を合わせたいか (関数名だけ? 戻り値? メソッド?) に応じて、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'>

            ...
于 2015-05-14T18:06:16.650 に答える
1

おそらく、Python デバッガー、またはPython プログラムの実行を追跡し、(インスタンス化したいクラスの)ブレークポイントが正しく設定された GUI バージョンのWinPDB__init__を探しているのであれば、すべてを見ることができます。インスタンス化につながったトレースバック。

于 2012-06-14T13:51:44.240 に答える