在调试 Python 脚本时,我真的很想知道整个程序的整个调用堆栈。理想的情况是,如果 python 有一个命令行标志,它会导致 Python 在调用时打印所有函数名称(我检查过man Python2.7
,但没有找到此类内容)。
由于此脚本中的函数数量较多,如果可能的话,我不希望在每个函数和/或类的开头添加打印语句。
中间解决方案是使用 PyDev 的调试器,放置几个断点并检查程序中给定点的调用堆栈,因此我暂时使用这种方法。
如果存在这样的方法,我仍然希望看到在程序的整个生命周期中调用的所有函数的完整列表。
您可以使用跟踪函数来做到这一点(支持 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.setprofile(tracefunc)
main() # or whatever kicks off your script
请注意,函数的代码对象通常与关联函数具有相同的名称,但并非总是如此,因为函数可以动态创建。不幸的是,Python 不跟踪堆栈上的函数对象(我有时幻想为此提交一个补丁)。尽管如此,在大多数情况下这确实“足够好”。
如果这成为一个问题,您可以从源代码中提取“真实”函数名称(Python 会跟踪文件名和行号),或者要求垃圾收集器找出哪个函数对象引用了代码对象。可能有多个函数共享代码对象,但它们中的任何一个名称都可能足够好。
四年后再次回顾这个问题时,我有必要提到,在 Python 2.6 及更高版本中,您可以通过使用获得更好的性能sys.setprofile()
而不是sys.settrace()
。可以使用相同的跟踪功能;只是只有在进入或退出函数时才会调用 profile 函数,因此函数内部的内容会全速执行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)