如何打印被调用的函数
在debuggingPython脚本时,我真的很想知道整个程序的整个调用堆栈。 一个理想的情况是,如果有一个Python的命令行标志,会导致Python打印所有函数名称,因为他们被称为(我检查了man Python2.7
,但没有发现这种types的东西)。
由于这个脚本中的函数的数量,如果可能的话,我不希望在每个函数和/或类的开头添加一个print语句。
一个中间的解决scheme是使用PyDev的debugging器,放置一对断点,并在程序中检查调用堆栈的给定点,所以暂时使用这种方法。
如果存在这样一种方法,我仍然希望看到在程序的整个生命周期中调用的所有函数的完整列表。
您可以使用跟踪function(支持Spacedman来改进原始版本以跟踪退货并使用一些很好的缩进)来完成此操作:
def tracefunc(frame, event, arg, indent=[0]): if event == "call": indent[0] += 2 print "-" * indent[0] + "> call function", frame.f_code.co_name elif event == "return": print "<" + "-" * indent[0], "exit function", frame.f_code.co_name indent[0] -= 2 return tracefunc import sys sys.settrace(tracefunc) main() # or whatever kicks off your script
请注意,函数的代码对象通常与相关函数具有相同的名称,但并不总是如此,因为可以dynamic地创build函数。 不幸的是,Python不会跟踪堆栈上的函数对象(我有时幻想着为此提交一个补丁)。 不过,在大多数情况下,这肯定是“足够好”的。
如果这变成了一个问题,你可以从源代码中提取“真实”的函数名,Python会跟踪文件名和行号,或者让垃圾收集器找出哪个函数对象引用了代码对象。 可能有多个函数共享代码对象,但是他们的名字可能是足够好的。
回过头来重温一下这四年之后,有必要提一下,在Python 2.6及更高版本中,通过使用sys.setprofile()
而不是sys.settrace()
可以获得更好的性能。 可以使用相同的跟踪function; 只是在函数被input或退出时调用configuration文件函数,所以函数内部全速执行。
有几个选项。 如果debugging器不够用,可以使用sys.settrace()
来设置跟踪function 。 这个函数实质上会在每行Python代码上执行,但是很容易识别函数调用 – 请参阅链接的文档。
您可能也对trace
模块感兴趣,尽pipe它并不完全符合您的要求。 一定要看看--trackcalls
选项。
另一个需要注意的好工具是跟踪模块:
$ cat foo.py def foo(): bar() def bar(): print "in bar!" foo() $ python -m trace --listfuncs foo.py in bar! functions called: filename: /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/trace.py, modulename: trace, funcname: _unsettrace filename: foo.py, modulename: foo, funcname: filename: foo.py, modulename: foo, funcname: bar filename: foo.py, modulename: foo, funcname: foo $python -m trace --trace foo.py --- modulename: foo, funcname: foo.py(1): def foo(): foo.py(4): def bar(): foo.py(7): foo() --- modulename: foo, funcname: foo foo.py(2): bar() --- modulename: foo, funcname: bar foo.py(5): print "in bar!" in bar! --- modulename: trace, funcname: _unsettrace trace.py(80): sys.settrace(None)
import traceback def foo(): traceback.print_stack() def bar(): foo() def car(): bar(): car() File "<string>", line 1, in <module> File "C:\Python27\lib\idlelib\run.py", line 97, in main ret = method(*args, **kwargs) File "C:\Python27\lib\idlelib\run.py", line 298, in runcode exec code in self.locals File "<pyshell#494>", line 1, in <module> File "<pyshell#493>", line 2, in car File "<pyshell#490>", line 2, in bar File "<pyshell#486>", line 2, in foo
追溯
您可以使用settrace,如下所示: 跟踪Python代码 。 使用靠近页面末尾的版本。 我把这个页面的代码粘贴到我的代码中,看看我的代码运行时究竟执行了哪些行。 您也可以过滤,以便只能看到所调用函数的名称。