关于调试:从Python代码中的方法打印当前调用堆栈

Print current call stack from a method in Python code

在python中,如何从方法中打印当前调用堆栈(用于调试)。


下面是通过回溯模块获取堆栈并打印它的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import traceback

def f():
    g()

def g():
    for line in traceback.format_stack():
        print(line.strip())

f()

# Prints:
# File"so-stack.py", line 10, in <module>
#     f()
# File"so-stack.py", line 4, in f
#     g()
# File"so-stack.py", line 7, in g
#     for line in traceback.format_stack():

如果只想将堆栈打印到stderr,可以使用:

1
traceback.print_stack()

或者,要打印到stdout(如果希望将重定向的输出保持在一起,则很有用),请使用:

1
traceback.print_stack(file=sys.stdout)

但是通过traceback.format_stack()获得它可以让你随心所欲地使用它。


1
2
import traceback
traceback.print_stack()


inspect.stack()返回当前堆栈,而不是异常回溯:

1
2
import inspect
print inspect.stack()

请参阅https://gist.github.com/fredloney/5454553了解日志堆栈实用程序函数。


如果使用python调试器,不仅可以交互式地探测变量,还可以使用"where"命令或"w"获取调用堆栈。

所以在你的计划的顶端

1
import pdb

然后在代码中你想看到发生了什么

1
pdb.set_trace()

然后你就会被提示


下面是@richiehindle的优秀答案的变体,它实现了一个装饰器,可以根据需要选择性地应用到函数中。适用于python 2.7.14和3.6.4。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from __future__ import print_function
import functools
import traceback
import sys

INDENT = 4*' '

def stacktrace(func):
    @functools.wraps(func)
    def wrapped(*args, **kwds):
        # Get all but last line returned by traceback.format_stack()
        # which is the line below.
        callstack = '
'
.join([INDENT+line.strip() for line in traceback.format_stack()][:-1])
        print('{}() called:'.format(func.__name__))
        print(callstack)
        return func(*args, **kwds)

    return wrapped

@stacktrace
def test_func():
    return 42

print(test_func())

样本输出:

1
2
3
4
test_func() called:
    File"stacktrace_decorator.py", line 28, in <module>
    print(test_func())
42