如何打印调用的函数?
在调试 Python 脚本时,我真的很想知道整个程序的整个调用堆栈。理想的情况是,如果 python 有一个命令行标志,它会导致 Python 在调用时打印所有函数名称(我检查了 man Python2.7
,但没有找到任何这种)。
由于此脚本中的函数数量较多,如果可能的话,我不希望在每个函数和/或类的开头添加打印语句。
中间解决方案是使用 PyDev 的调试器,放置几个断点并检查程序中给定点的调用堆栈,因此我暂时使用这种方法。
如果存在这样的方法,我仍然希望看到在程序的整个生命周期中调用的所有函数的完整列表。
In debugging a Python script, I'd really like to know the entire call stack for my entire program. An ideal situation would be if there were a command-line flag for python that would cause Python to print all function names as they are called (I checked man Python2.7
, but didn't find anything of this sort).
Because of the number of functions in this script, I'd prefer not to add a print statement to the beginning of each function and/or class, if possible.
An intermediate solution would be to use PyDev's debugger, place a couple breakpoints and check the call stack for given points in my program, so I'll use this approach for the time being.
I'd still prefer to see a complete list of all functions called throughout the life of the program, if such a method exists.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您可以使用跟踪函数来做到这一点(支持 Spacedman 改进其原始版本以跟踪返回并使用一些漂亮的缩进):
请注意,函数的代码对象通常与关联函数具有相同的名称,但并非总是如此,因为可以动态创建函数。不幸的是,Python 不跟踪堆栈上的函数对象(我有时幻想为此提交一个补丁)。尽管如此,在大多数情况下这确实“足够好”。
如果这成为一个问题,您可以从源代码中提取“真实”函数名称(Python 会跟踪文件名和行号),或者要求垃圾收集器找出哪个函数对象引用了代码对象。可能有多个函数共享代码对象,但它们中的任何一个名称都可能足够好。
四年后再次回顾这一点时,我有必要提到,在 Python 2.6 及更高版本中,您可以通过使用
sys.setprofile()
而不是获得更好的性能>sys.settrace()
。可以使用相同的跟踪功能;只是只有在进入或退出函数时才会调用配置文件函数,因此函数内部的内容会全速执行。You can do this with a trace function (props to Spacedman for improving the original version of this to trace returns and use some nice indenting):
Note that a function's code object usually has the same name as the associated function, but not always, since functions can be created dynamically. Unfortunately, Python doesn't track the function objects on the stack (I've sometimes fantasized about submitting a patch for this). Still, this is certainly "good enough" in most cases.
If this becomes an issue, you could extract the "real" function name from the source code—Python does track the filename and line number—or ask the garbage collector find out which function object refers to the code object. There could be more than one function sharing the code object, but any of their names might be good enough.
Coming back to revisit this four years later, it behooves me to mention that in Python 2.6 and later, you can get better performance by using
sys.setprofile()
rather thansys.settrace()
. The same trace function can be used; it's just that the profile function is called only when a function is entered or exited, so what's inside the function executes at full speed.另一个需要注意的好工具是 trace 模块。显示函数名称有 3 个选项。
示例
foo.py
:-l/--listfuncs
来列出函数:-t/--trace
> 列出执行的行。-T/--trackcalls
来列出什么调用什么Another good tool to be aware of is the trace module. There are 3 options of showing function names.
Example
foo.py
:-l/--listfuncs
to list funtions:-t/--trace
to list lines as they are executed.-T/--trackcalls
to list what calls what我接受了kindall的答案并以此为基础。我制作了以下模块:
示例用法
示例输出:
特点:
I took kindall's answer and built on it. I made the following module:
Sample usage
Sample output:
Features:
有几种选择。如果调试器还不够,您可以使用
sys.settrace()
。该函数本质上会在执行的每一行 Python 代码上被调用,但很容易识别函数调用——请参阅链接的文档。您可能还对
trace
模块感兴趣,尽管它并没有完全按照你的要求做。请务必查看--trackcalls
选项。There are a few options. If a debugger isn't enough, you can set a trace function using
sys.settrace()
. This function will be essentially called on every line of Python code executed, but it easy to identify the function calls -- see the linked documentation.You might also be interested in the
trace
module, though it doesn't do exactly what you asked for. Be sure to look into the--trackcalls
option.回溯
traceback
hunter
工具正是这样做的,甚至更多。例如,给定:test.py:
输出如下所示:
它还提供了非常灵活的查询语法,允许指定模块、文件/行号、函数等,这会有所帮助,因为默认输出(其中包括标准库函数调用)可能相当大。
The
hunter
tool does exactly this, and more. For example, given:test.py:
The output looks like:
It also provides a pretty flexible query syntax that allows specifying module, file/lineno, function, etc which helps because the default output (which includes standard library function calls) can be pretty big.
您可以使用settrace,如下所述: 跟踪 python 代码< /a>.使用靠近页面末尾的版本。我将该页面的代码粘贴到我的代码中,以准确查看代码运行时执行了哪些行。您还可以进行过滤,以便只看到调用的函数的名称。
You could use settrace, as outlined here: Tracing python code. Use the version near the end of the page. I stick the code of that page into my code to see exactly what lines are executed when my code is running. You can also filter so that you only see the names of functions called.
您还可以对要跟踪的特定函数(及其参数)使用装饰器:
只需导入此文件并在要跟踪的函数/方法之前添加 @TraceCalls() 即可。
You can also use a decorator for specific functions you want to trace (with their arguments):
Just import this file and add a @TraceCalls() before the function/method you want to trace.
kindall 答案的变体,仅返回包中被调用的函数。
例如,在名为
Dog
的包中,这应该只显示在Dog
包中定义的调用函数。Variation on kindall's answer, return just the called functions in a package.
e.g. In a package called
Dog
, this should only show you functions called that were defined in theDog
package.