Python 코드의 메소드에서 현재 호출 스택 인쇄


276

파이썬에서는 메소드 내에서 디버깅을 위해 현재 호출 스택을 어떻게 인쇄 할 수 있습니까?

답변:


319

다음은 트레이스 백 모듈을 통해 스택을 가져 와서 인쇄하는 예입니다.

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()

또는 stdout으로 인쇄하려면 (리디렉션 된 출력을 함께 유지하려는 경우 유용) 다음을 사용하십시오.

traceback.print_stack(file=sys.stdout)

그러나 그것을 통해 얻는 traceback.format_stack()것은 당신이 그것을 좋아하는 무엇이든 할 수 있습니다.


다른 모든 스레드에 대해 동일한 작업을 수행하는 방법 (제어하지 않는 스레드에 대해 이야기하고 있음)  ?
user2284570

어쩌면 나는 여기에 뭔가 빠졌지 만, 여기에 목적이있는 f는 g를 호출하고 다른 것은 아무것도하지 않는 것입니다. 이유
Chris

6
@Chris : 단지 예일뿐입니다. format_stack ()이 스택의 모든 호출을 인쇄한다는 것을 분명히하기 위해 여러 함수가 있습니다.
RichieHindle

좀 더 장황한 출력 (vars 등 포함)을 얻으려면 이 관련 질문this을 참조하십시오 .
Albert

@ user2284570 : 사용할 수 있습니다 sys._current_frames(). 예를 들어 py_better_exchookdump_all_thread_tracebacks 는 그렇게합니다 (면책 조항 : 나는 그것을 썼습니다).
Albert

93
import traceback
traceback.print_stack()

8
실제로, 나는 traceback.print_exc()당신에게 except진술 없이 얻을 수있는 것과 거의 동일한 것을 제공합니다 (그리고 받아 들인 대답보다 코딩이 적습니다).
martineau

34
traceback.print_exc()처리 할 수있는 예외에 대한 스택 추적을 인쇄합니다. 그러나 이것은 원래 질문을 해결하지 못합니다. 이것은 "마지막 예외가 갔을 때 코드가 있었던 위치와 달리 현재 스택 을 인쇄하는 방법 "( 현재 위치) 꺼져 있다면. ")
Tom Swirly


17

파이썬 디버거를 사용하는 경우 대화식 변수 탐색뿐만 아니라 "where"명령 또는 "w"를 사용하여 호출 스택을 얻을 수 있습니다.

프로그램 상단에

import pdb

그런 다음 무슨 일이 일어나고 있는지보고 싶은 코드에서

pdb.set_trace()

그리고 당신은 프롬프트에 빠지게됩니다


2
저는 10 년 넘게 파이썬으로 프로그래밍을 해왔습니다. 있다 그래서 나는이를 사용할 수도 여러 번! 나는 지금 막 그것에 대해 알고 있다고 믿을 수 없다.
hosford42

1
이것은 어떻게 관련이 where있습니까?
skia.heliou 2018 년

4
질문의 "where"부분에 대답하려면 : pdb 프롬프트가 나타난 후 (pdb) 그냥 입력 where하면 스택 추적이 터미널에 인쇄됩니다.
stephenmm

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

이것을보기 전에 내 데코레이터 버전을 작성했습니다. 공감.
Sida Zhou

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()])

이 줄의 스 니펫을 만들 수 있습니다

파일 이름과 줄 번호 가있는 함수 호출 스택 목록이 표시됩니다

이 줄을 처음부터 끝까지 나열하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.