Вывести текущий стек вызовов из метода в коде Python


Ответы:


319

Вот пример получения стека через модуль 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()позволяет делать с ним все, что угодно.


Как сделать то же самое для всех других потоков (я говорю о потоках, которые я не контролирую)  ?
user2284570

Может быть, я что-то здесь упускаю, но вы называете f, единственная цель которой здесь, это вызвать g и больше ничего не делает. Почему
Крис

6
@ Крис: Это просто пример. Он имеет несколько функций, чтобы было ясно, что format_stack () печатает все вызовы в стеке.
RichieHindle

Если вы хотите получить более подробный вывод (включая vars и т. Д.), Посмотрите этот связанный вопрос и этот .
Альберт

@ user2284570: Вы можете использовать sys._current_frames(). Например, py_better_exchookdump_all_thread_tracebacks делает это (отказ от ответственности: я это написал).
Альберт

93
import traceback
traceback.print_stack()

8
На самом деле, мне нравится, traceback.print_exc()что дает вам почти то же самое, что вы получили бы без exceptутверждения (и также менее кодирующе, чем принятый ответ).
Мартино

34
traceback.print_exc()печатает трассировку стека для любого исключения, которое вы, возможно, обрабатываете - но это не решает первоначальный вопрос, а именно, как напечатать текущий стек («где вы сейчас находитесь», а не «где был ваш код, когда было последнее исключение»). выкл, если есть ".)
Том Свирли


17

Если вы используете отладчик Python, не только интерактивное исследование переменных, но вы можете получить стек вызовов с помощью команды «где» или «w».

Так что в верхней части вашей программы

import pdb

Затем в коде, где вы хотите увидеть, что происходит

pdb.set_trace()

и вы попадете в подсказку


2
Я программирую на Python более десяти лет. Есть так много раз , я мог бы использовать это! Я не могу поверить, что только сейчас узнаю об этом.
hosford42

1
Как это связано с where?
skia.heliou

4
Чтобы ответить на вопрос «где»: после того, как вы получите приглашение pdb, (pdb) просто наберите, whereи он выведет трассировку стека на терминал.
Стивенм

1
Python 3.7 и выше имеют встроенную функцию, breakpoint()которая устраняет необходимость импорта pdb.
user650654

6

для тех, кому нужно распечатать стек вызовов при использовании pdb, просто сделайте

(Pdb) where

2

Вот вариант отличного ответа @ 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

Написал свой собственный вариант декоратора, прежде чем я увидел это. Upvoted.
Сида Чжоу

0

Установите Inspect-it

pip3 install inspect-it --user

Код

import inspect;print(*['\n\x1b[0;36;1m| \x1b[0;32;1m{:25}\x1b[0;36;1m| \x1b[0;35;1m{}'.format(str(x.function), x.filename+'\x1b[0;31;1m:'+str(x.lineno)+'\x1b[0m') for x in inspect.stack()])

Вы можете сделать фрагмент этой строки

он покажет вам список стека вызовов функций с именем файла и номером строки

список от начала, где вы положили эту строку

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.