ChatGPT解决这个技术问题 Extra ChatGPT

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

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


Q
Quentin Pradet

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

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,您可以使用:

traceback.print_stack()

或者打印到标准输出(如果想保持重定向输出一起有用),使用:

traceback.print_stack(file=sys.stdout)

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


如何对所有其他线程做同样的事情(我说的是我不控制的线程)?
也许我在这里遗漏了一些东西,但是你调用 f ,它的唯一目的是调用 g 并且什么都不做。为什么
@Chris:这只是一个例子。它有多个函数来明确 format_stack() 打印堆栈上的所有调用。
如果您想获得更详细的输出(包括变量等),请参阅 this related questionthis one
@user2284570:您可以使用 sys._current_frames()。例如 py_better_exchook dump_all_thread_tracebacks 这样做(免责声明:我写了那个)。
M
Mark Roddy
import traceback
traceback.print_stack()

实际上,我喜欢 traceback.print_exc() ,它给你的东西几乎与没有 except 语句的情况相同(而且编码也比接受的答案少)。
traceback.print_exc() 打印您可能正在处理的任何异常的堆栈跟踪 - 但这并不能解决原始问题,即如何打印 current 堆栈(“您现在所在的位置”而不是“最后一次异常发生时你的代码在哪里,如果有的话”。)
将跟踪限制为多个条目可能很有用,例如:traceback.print_stack(limit=4)
F
Fred Loney

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

import inspect
print inspect.stack()

有关 log_stack 实用程序函数,请参见 https://gist.github.com/FredLoney/5454553


m
mouserat

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

(Pdb) where

K
Keir

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

所以在你的程序的顶部

import pdb

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

pdb.set_trace()

然后你会进入提示


我已经用 Python 编程十多年了。有很多次我可以用这个!我不敢相信我现在才知道这件事。
这与 where 有何关系?
要回答问题的“位置”部分:在得到 pdb 提示符 (pdb) 后,只需键入 where,它就会将堆栈跟踪打印到终端。
Python 3.7 及更高版本有一个内置函数 breakpoint(),它消除了导入 pdb 的需要。
对于在 jupyter notebook 中尝试此操作的任何人的注意事项:在提示中输入 exit() 以使单元格完成执行。
m
martineau

这是@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())

样本输出:

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

在我看到这个之前写了我自己的装饰器版本。赞成。
M
MohitGhodasara

安装检查它

pip3 install inspect-it --user

代码

import inspect;print(*['{:40}| {}:{}\n'.format(x.function, x.filename, x.lineno) for x in inspect.stack()])

你可以制作这一行的片段

它将向您显示带有文件名和行号的函数调用堆栈列表

列出从开始到您放置此行的位置