33

次のスニペット:

import traceback

def a():
    b()

def b():
    try:
        c()
    except:
        traceback.print_exc()

def c():
    assert False

a()

この出力を生成します:

Traceback (most recent call last):
  File "test.py", line 8, in b
    c()
  File "test.py", line 13, in c
    assert False
AssertionError

の呼び出しを含む完全なスタックトレースが必要な場合は、何を使用すればよいですか?

重要な場合はPython2.6.6を使用しています

編集:私が取得したいのは、例外を除いて試行を終了し、例外をトップレベルに伝播させた場合に取得するのと同じ情報です。たとえば、このスニペットは次のとおりです。

def a():
    b()

def b():
    c()

def c():
    assert False

a()

この出力を生成します:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    a()
  File "test.py", line 2, in a
    b()
  File "test.py", line 5, in b
    c()
  File "test.py", line 8, in c
    assert False
AssertionError
4

4 に答える 4

31

これがこの答えに基づく関数です。例外が存在しない場合にも機能します。

def full_stack():
    import traceback, sys
    exc = sys.exc_info()[0]
    stack = traceback.extract_stack()[:-1]  # last one would be full_stack()
    if exc is not None:  # i.e. an exception is present
        del stack[-1]       # remove call of full_stack, the printed exception
                            # will contain the caught exception caller instead
    trc = 'Traceback (most recent call last):\n'
    stackstr = trc + ''.join(traceback.format_list(stack))
    if exc is not None:
         stackstr += '  ' + traceback.format_exc().lstrip(trc)
    return stackstr

print full_stack()interactiveshell.py誰が例外をキャッチするかを知る方法がないため、たとえばIPythonの呼び出しを含め、スタックトレース全体を一番上まで出力します。とにかく理解する価値はないでしょう...

ブロックprint full_stack()内からが呼び出された場合、までのスタックトレースが含まれます。標準のPythonインタープリターでは、これは例外をキャッチしないときに受信するメッセージと同じになります(そのため、ブロックは気にせず、ブロックを気にします)。exceptfull_stackraisedel stack[-1]excepttry

于 2013-05-16T14:04:47.590 に答える
22

より良い方法があるかどうかはわかりませんが、これが私がしたことです:

import traceback
import sys

def format_exception(e):
    exception_list = traceback.format_stack()
    exception_list = exception_list[:-2]
    exception_list.extend(traceback.format_tb(sys.exc_info()[2]))
    exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1]))

    exception_str = "Traceback (most recent call last):\n"
    exception_str += "".join(exception_list)
    # Removing the last \n
    exception_str = exception_str[:-1]

    return exception_str

def main1():
    main2()

def main2():
    try:
        main3()
    except Exception as e:
        print "Printing only the traceback above the current stack frame"
        print "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))
        print
        print "Printing the full traceback as if we had not caught it here..."
        print format_exception(e)

def main3():
    raise Exception()

if __name__ == '__main__':
    main1()

そして、これが私が得る出力です:

Printing only the traceback above the current stack frame
Traceback (most recent call last):
  File "exc.py", line 22, in main2
    main3()
  File "exc.py", line 31, in main3
    raise Exception()
Exception


Printing the full traceback as if we had not caught it here...
Traceback (most recent call last):
  File "exc.py", line 34, in <module>
    main1()
  File "exc.py", line 18, in main1
    main2()
  File "exc.py", line 22, in main2
    main3()
  File "exc.py", line 31, in main3
    raise Exception()
Exception
于 2012-09-21T23:21:35.263 に答える
11

使用する

 traceback.print_stack()

http://docs.python.org/library/traceback.html#traceback.print_stack

suxmac2 $ python out.py 
  File "out.py", line 16, in <module>
    a()
  File "out.py", line 5, in a
    b()
  File "out.py", line 11, in b
    traceback.print_stack()
于 2011-05-22T09:16:49.540 に答える
5


TobiasKienzlerの回答 のも​​う少し良い変形があります。exceptそれは同じように機能しますが、ブロック内ではなく、どこかより深い場所で呼び出すことができます。言い換えれば、このバリアントは、次のように呼び出されたときに同じスタックを出力します

try:
   ...
except Exception:
    print full_stack()

また

def print_full_stack():
    print full_stack()

try:
   ...
except Exception:
    print_full_stack()

コードは次のとおりです。

def full_stack():
    import traceback, sys
    exc = sys.exc_info()[0]
    if exc is not None:
        f = sys.exc_info()[-1].tb_frame.f_back
        stack = traceback.extract_stack(f)
    else:
        stack = traceback.extract_stack()[:-1]  # last one would be full_stack()
    trc = 'Traceback (most recent call last):\n'
    stackstr = trc + ''.join(traceback.format_list(stack))
    if exc is not None:
        stackstr += '  ' + traceback.format_exc().lstrip(trc)
    return stackstr
于 2017-11-12T09:14:35.293 に答える