您可以使用跟踪功能做到这一点(道具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
注意函数的代码对象通常具有相同名称作为关联函数,但并非总是如此,因为函数可以动态创建。不幸的是,Python不会跟踪堆栈上的函数对象(我有时幻想着为此提交一个补丁)。不过,在大多数情况下,这肯定是“足够好”的。
如果出现这个问题,可以从源代码中提取“真实”函数名称--Python确实跟踪文件名和行号 - 或者让垃圾收集器找出哪个函数对象引用了代码对象。可能有多个函数共享代码对象,但他们的任何名字都可能足够好。
反观四年后重温这一点,我理应提的是Python 2.6和更高版本,可以通过使用sys.setprofile()
而不是sys.settrace()
获得更好的性能。可以使用相同的跟踪功能;只是当函数被输入或退出时才调用配置文件函数,所以函数内部全速执行。
分析器告诉你,例如所谓的所有功能http://docs.python.org/library/profile.html但不完全是你所要求的 - 这足够吗? – Mark