次のスニペット:
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
への呼び出しを含む完全なスタックトレースが必要な場合、何を使用すればよいですか?
それが重要であれば、Python 2.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
より良い方法があるかどうかはわかりませんが、これが私がしたことです:
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
これが this answer に基づく関数です。例外が存在しない場合にも機能します。
_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()
は、スタックトレース全体を先頭まで出力します。 IPythonの_interactiveshell.py
_呼び出し。とにかくそれを理解する価値はありません...
except
ブロック内からprint full_stack()
が呼び出された場合、_full_stack
_にはraise
までのスタックトレースが含まれます。標準のPythonインタプリタでは、これは例外をキャッチしないときに受け取るメッセージと同じです(そのため、_del stack[-1]
_が存在するのはそのため、except
は気にしません)ブロック、ただしtry
ブロックについて)。
使用する
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()
これが トビアスキエンツラーの回答 のもう少し良い変形です。同じように機能しますが、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