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

one*_*elf 257 python debugging stack-trace

在Python中,如何从方法中打印当前调用堆栈(用于调试目的).

Ric*_*dle 294

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

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():
Run Code Online (Sandbox Code Playgroud)

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

traceback.print_stack()
Run Code Online (Sandbox Code Playgroud)

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

traceback.print_stack(file=sys.stdout)
Run Code Online (Sandbox Code Playgroud)

但通过它可以traceback.format_stack()让你做任何你喜欢的事情.

  • 作为字符串:`stack_str =''.join(traceback.format_stack())` (9认同)
  • @Chris:这只是一个例子.它有多个函数可以清楚地表明format_stack()打印了堆栈上的所有调用. (5认同)

Mar*_*ddy 89

import traceback
traceback.print_stack()
Run Code Online (Sandbox Code Playgroud)

  • `traceback.print_exc()`为你可能正在处理的任何异常打印堆栈跟踪 - 但这并不能解决原始问题,即如何打印_current_堆栈("你现在在哪里"而不是"你在哪里"代码是最后一个异常消失的时候,如果有的话.") (32认同)
  • 实际上,我喜欢`traceback.print_exc()`,它给你几乎与没有`except`语句时相同的东西(并且编码也比接受的答案少). (8认同)
  • 将跟踪限制为多个条目可能很有用,例如:traceback.print_stack(limit=4) (2认同)

Fre*_*ney 40

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

import inspect
print inspect.stack()
Run Code Online (Sandbox Code Playgroud)

有关log_stack实用程序功能,请参阅https://gist.github.com/FredLoney/5454553.

  • 应该有更多的选票,“inspect”*感觉*使用起来更好。 (3认同)

mou*_*rat 25

对于那些在使用 pdb 时需要打印调用堆栈的人,只需执行

(Pdb) where
Run Code Online (Sandbox Code Playgroud)


Kei*_*eir 14

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

所以在你的程序的顶部

import pdb
Run Code Online (Sandbox Code Playgroud)

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

pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)

然后你就会陷入提示

  • 这与“哪里”有什么关系? (3认同)
  • 要回答问题的“ where”部分:在得到pdb提示`(pdb)`之后,只需键入`where`,它将把堆栈跟踪信息打印到终端。 (3认同)
  • 我已经用 Python 编程十多年了。有很多次我可以使用它!我简直不敢相信我现在才知道。 (2认同)

mar*_*eau 5

这是 @RichieHindle 的优秀答案的一个变体,它实现了一个装饰器,可以根据需要有选择地应用于函数。适用于 Python 2.7.14 和 3.6.4。

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 = '\n'.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())
Run Code Online (Sandbox Code Playgroud)

样本输出:

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 = '\n'.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())
Run Code Online (Sandbox Code Playgroud)