1096

終了せずに例外をキャッチしてログに記録したい。

try:
    do_stuff()
except Exception as err:
    print(Exception, err)
    # I want to print the entire traceback here,
    # not just the exception name and details

try..except が例外をインターセプトせずに例外が発生したときに出力されるのとまったく同じ出力を出力したいのですが、プログラムを終了させたくありません。どうすればいいですか?

4

18 に答える 18

930

traceback.format_exc()または、それsys.exc_info()が必要な場合は、より多くの情報が得られます。

import traceback
import sys

try:
    do_stuff()
except Exception:
    print(traceback.format_exc())
    # or
    print(sys.exc_info()[2])
于 2010-09-13T17:27:26.443 に答える
328

デバッグ中に現在のスタック トレースを確認したいだけの場合は、次のように呼び出すだけです。

traceback.print_stack()

再度キャッチするためだけに手動で例外を発生させる必要はありません。

于 2015-04-28T21:40:32.830 に答える
176

プログラムを停止せずに完全なトレースバックを出力するには?

エラーでプログラムを停止したくない場合は、そのエラーを try/except で処理する必要があります。

try:
    do_something_that_might_error()
except Exception as error:
    handle_the_error(error)

完全なトレースバックを抽出するにはtraceback、標準ライブラリのモジュールを使用します。

import traceback

そして、かなり複雑なスタックトレースを作成して、完全なスタックトレースを取得できることを示します。

def raise_error():
    raise RuntimeError('something bad happened!')

def do_something_that_might_error():
    raise_error()

印刷

完全なトレースバックを出力するには、次のメソッドを使用しますtraceback.print_exc

try:
    do_something_that_might_error()
except Exception as error:
    traceback.print_exc()

どちらが印刷されますか:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!

印刷、ログ記録よりも優れています:

ただし、ベスト プラクティスは、モジュールにロガーを設定することです。モジュールの名前を認識し、レベルを変更できます (ハンドラーなどの他の属性の中で)。

import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

その場合、logger.exception代わりに関数が必要になります。

try:
    do_something_that_might_error()
except Exception as error:
    logger.exception(error)

どのログ:

ERROR:__main__:something bad happened!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!

または、単に文字列が必要な場合は、traceback.format_exc代わりに関数が必要になります。

try:
    do_something_that_might_error()
except Exception as error:
    logger.debug(traceback.format_exc())

どのログ:

DEBUG:__main__:Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!

結論

3 つのオプションすべてについて、エラーが発生した場合と同じ出力が得られることがわかります。

>>> do_something_that_might_error()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in do_something_that_might_error
  File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!

どちらを使用するか

通常は IO が支配的であるため、ここではパフォーマンスの問題は重要ではありません。前方互換性のある方法で要求されていることを正確に実行するため、私は好むでしょう:

logger.exception(error)

ロギング レベルと出力を調整できるため、コードに触れることなく簡単にオフにすることができます。通常、直接必要なことを実行することが最も効率的な方法です。

于 2015-07-16T03:23:54.867 に答える
27

traceback.format_exception(exception_object)

例外オブジェクトしかない場合は、Python 3 のコードの任意のポイントからトレースバックを文字列として取得できます。

import traceback

''.join(traceback.format_exception(None, exc_obj, exc_obj.__traceback__))

完全な例:

#!/usr/bin/env python3

import traceback

def f():
    g()

def g():
    raise Exception('asdf')

try:
    g()
except Exception as e:
    exc_obj = e

tb_str = ''.join(traceback.format_exception(None, exc_obj, exc_obj.__traceback__))
print(tb_str)

出力:

Traceback (most recent call last):
  File "./main.py", line 12, in <module>
    g()
  File "./main.py", line 9, in g
    raise Exception('asdf')
Exception: asdf

ドキュメント: https://docs.python.org/3.9/library/traceback.html#traceback.format_exception

関連項目:例外オブジェクトからトレースバック情報を抽出する

Python 3.9 でテスト済み

于 2019-05-18T13:14:17.747 に答える
8

エラーが発生する可能性がある最も内側のループ内に try/except を配置する必要があります。つまり、

for i in something:
    for j in somethingelse:
        for k in whatever:
            try:
                something_complex(i, j, k)
            except Exception, e:
                print e
        try:
            something_less_complex(i, j)
        except Exception, e:
            print e

... 等々

つまり、try/except で失敗する可能性のあるステートメントは、できるだけ具体的に、できるだけ内側のループにラップする必要があります。

于 2010-09-13T17:10:16.337 に答える
7

この回答のコメントについてのコメント:print(traceback.format_exc())よりも私にとっては良い仕事をしますtraceback.print_exc()。後者のhello場合、両方が stdout または stderr に同時に書き込みたい場合のように、トレースバック テキストと奇妙に "混合" されることがあり、奇妙な出力が生成されます (少なくともテキスト エディター内からビルドし、出力を「ビルド結果」パネル)。

トレースバック (最新の呼び出しが最後):
ファイル "C:\Users\User\Desktop\test.py"、7 行目、
地獄 の do_stuff()
ファイル "C:\Users\User\Desktop\test.py"、4 行目、do_stuff
1/0
ZeroDivisionError: ゼロによる整数除算またはモジュロ
o
[0.1 秒で終了]

だから私は使用します:

import traceback, sys

def do_stuff():
    1/0

try:
    do_stuff()
except Exception:
    print(traceback.format_exc())
    print('hello')
于 2018-11-06T17:18:38.817 に答える
3

tracebackモジュールが必要です。Python が通常行うように、スタック ダンプを出力できます。特に、print_last関数は最後の例外とスタック トレースを出力します。

于 2010-09-13T17:11:12.873 に答える