1. ホーム
  2. パイソン

[解決済み】プログラムを停止/終了させることなく、完全な例外トレースバックをキャッチして表示する方法は?

2022-03-23 13:13:49

質問

終了せずに例外をキャッチしてログに残したいのですが、例えば。

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...以外では出力したいのですが、どうすればいいでしょうか? ない 私のプログラムを終了させたいのです。 どうしたらいいでしょうか?

解決方法は?

他の回答で既に指摘されている トレースバック モジュールを使用します。

を使用していることに注意してください。 print_exc このような場合、期待するような結果が得られないことがあります。Python 2.xの場合。

import traceback

try:
    raise TypeError("Oups!")
except Exception, err:
    try:
        raise TypeError("Again !?!")
    except:
        pass

    traceback.print_exc()

...のトレースバックを表示します。 最後の 例外が発生します。

Traceback (most recent call last):
  File "e.py", line 7, in <module>
    raise TypeError("Again !?!")
TypeError: Again !?!

どうしてもオリジナルの トレースバック をキャッシュするのもひとつの方法です。 例外情報 から返されるように exc_info をローカル変数に入れ、それを print_exception :

import traceback
import sys

try:
    raise TypeError("Oups!")
except Exception, err:
    try:
        exc_info = sys.exc_info()

        # do you usefull stuff here
        # (potentially raising an exception)
        try:
            raise TypeError("Again !?!")
        except:
            pass
        # end of useful stuff


    finally:
        # Display the *original* exception
        traceback.print_exception(*exc_info)
        del exc_info

プロデュースすること。

Traceback (most recent call last):
  File "t.py", line 6, in <module>
    raise TypeError("Oups!")
TypeError: Oups!

しかし、これにはいくつかの落とし穴があります。

  • のドキュメントから sys_info :

    例外を処理している関数内でトレースバックの戻り値をローカル変数に代入すると 循環参照 . このため、同じ関数内のローカル変数やトレースバックから参照されたものは、ガベージコレクションされなくなります。[...] トレースバックが必要な場合は、使用後に必ず削除してください。 (try...finallyステートメントで行うのがベスト)

  • が、同じdocから。

    Python 2.2 以降、このようなサイクルは自動的に再生されます。 しかし、サイクルを作成しない方がより効率的であることに変わりはありません。


一方、トレースバックにアクセスできるようにすることで に関連する は、あまり驚かない結果をもたらします。

import traceback

try:
    raise TypeError("Oups!")
except Exception as err:
    try:
        raise TypeError("Again !?!")
    except:
        pass

    traceback.print_tb(err.__traceback__)

...が表示されます。

  File "e3.py", line 4, in <module>
    raise TypeError("Oups!")