私はあなたと同じ船に乗っていました。結局、私は自分のものを作成しました。つまり、これに使用できる組み込みの方法がたくさんありますが、少し手間がかかります。そのような方法の 1 つは、トレーサー(実行中のコードのある種のアナライザー) を設定することです。
ソース:
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)
使用法
あなたの場合、次のように入力するだけです:
tracer = Tracer()
tracer.watch_package('IPython')
sys.settrace(tracer.trace)
次に、関数を実行しようとすると、呼び出されている同じパッケージの他の関数を含む呼び出しチェーン全体が出力されます。
その他の例
特定の機能の流れやパッケージ全体の流れを知りたいときに使います。パッケージ全体の俯瞰図が必要な場合は、pylintの pyreverse を使用して UML ダイアグラムを作成することもできます。
とにかく、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'>
...