Pythonコードのメソッドから現在の呼び出しスタックを出力する


276

Pythonでは、(デバッグ目的で)メソッド内から現在のコールスタックを出力するにはどうすればよいですか。

回答:


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 2017

多分私はここに何かが足りないかもしれませんが、あなたはそれを唯一の目的とするfをここに呼びます、それはgを呼ぶことで他には何もしません 理由
クリス

6
@クリス:それは単なる例です。format_stack()がスタック上のすべての呼び出しを出力することを明確にするために、複数の関数があります。
RichieHindle 2017

さらに詳細な出力(varsなどを含む)を取得したい場合は、この関連する質問これを参照してください。
アルバート

@ user2284570:を使用できますsys._current_frames()。例えばpy_better_exchookdump_all_thread_tracebacksはそれを行います(免責事項:私はそれを書きました)。
アルバート

93
import traceback
traceback.print_stack()

8
実際、私traceback.print_exc()はあなたがexceptステートメントなしで得たのとほぼ同じものを与えるのが好きです(そしてまた受け入れられた答えよりもコーディングが少ないです)。
martineau

34
traceback.print_exc()処理している可能性のあるすべての例外のスタックトレースを出力しますが、これは元の質問を解決しません。これは、「最後の例外が発生したときのコードの場所」ではなく、現在のスタック(「現在の場所」)を出力する方法です。オフ、もしあれば」)
Tom Swirly

44

inspect.stack() 例外トレースバックではなく、現在のスタックを返します。

import inspect
print inspect.stack()

log_stackユーティリティー関数については、https: //gist.github.com/FredLoney/5454553を参照してください


17

Pythonデバッガーを使用する場合は、変数のインタラクティブなプローブだけでなく、「where」コマンドまたは「w」を使用してコールスタックを取得できます。

プログラムの一番上に

import pdb

次に、何が起こっているのかを見たいコードで

pdb.set_trace()

プロンプトに落ちる


2
私は10年以上もPythonでプログラミングしています。ありますので、私はこれを使用している可能性が何度も!私は今それについて調べているとは信じられません。
hosford42

1
これはどのように関係していwhereますか?
skia.heliou

4
質問の「どこ」の部分に答えるには:pdbプロンプトが表示されたら、(pdb) 単に入力するwhereと、スタックトレースがターミナルに出力されます。
stephenmm 2018年

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.