我正在嘗試從一些開源python項目(如ipython)讀取一些源代碼。我經常發現很難遵循不同類中方法的執行流程,甚至使用eclipse的調試工具並逐步執行代碼。我不太清楚爲什麼代碼跳轉到遠程相關類中的某些方法。如何在python中執行方法執行
我知道它必須是繼承層次結構,但我覺得很難遵循。有什麼工具可以幫助理解代碼的執行方式嗎?像可視化不同方法的執行順序一樣?希望這不是一個完全天真的問題。
謝謝。
我正在嘗試從一些開源python項目(如ipython)讀取一些源代碼。我經常發現很難遵循不同類中方法的執行流程,甚至使用eclipse的調試工具並逐步執行代碼。我不太清楚爲什麼代碼跳轉到遠程相關類中的某些方法。如何在python中執行方法執行
我知道它必須是繼承層次結構,但我覺得很難遵循。有什麼工具可以幫助理解代碼的執行方式嗎?像可視化不同方法的執行順序一樣?希望這不是一個完全天真的問題。
謝謝。
跳轉是由您的函數調用另一個函數引起的,它調用另一個函數。
MIT網站有跟蹤執行,並將其顯示在畫面,你會發現有用的程序: http://people.csail.mit.edu/pgbovine/python/tutor.html#mode=edit
這是非常整潔,感謝您的鏈接 – Levon
我是在同一條船上,你。最後我創造了我自己的東西。也就是說,您可以使用許多內置方式,但需要付出一些努力。其中一種方法是設置一個示蹤器 - 執行代碼時的某種分析器。
來源:
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'>
...
你見過或試過的任何代碼圖「分析」工具? – sarnold
@sarnold剛剛嘗試了一個名爲pycallgraph的python模塊,它看起來很棒。 – qkhhly