1. ホーム
  2. パイソン

[解決済み】python: どのような例外が発生したかを知るにはどうすればよいですか?

2022-03-29 19:38:16

質問

メインプログラムから呼び出される関数があります。

try:
    someFunction()
except:
    print "exception happened!"

が、関数実行の途中で例外が発生し、そのため except の部分があります。

で何が起こったかを正確に知るにはどうすればよいのでしょうか? someFunction() 例外を発生させる原因となったのは?

解決方法は?

他の回答はすべて、一般的な例外をキャッチすべきではないことを指摘していますが、誰もその理由を言いたがっていないようです。 これ がその説明です。基本的には、隠れないようにするためです。

つまり、これらのことをしないように気をつければ、汎用例外をキャッチしても問題ないわけです。例えば、例外に関する情報を別の方法でユーザーに提供することもできます、以下のように。

  • GUIで例外をダイアログとして表示する
  • マルチスレッドまたはマルチプロセッシングアプリケーションにおいて、ワーカスレッドまたはプロセスから制御スレッドまたはプロセスへ例外を転送する。

では、汎用的な例外をキャッチするにはどうしたらよいのでしょうか。いくつかの方法があります。もし例外オブジェクトが欲しいだけなら、次のようにします。

try:
    someFunction()
except Exception as ex:
    template = "An exception of type {0} occurred. Arguments:\n{1!r}"
    message = template.format(type(ex).__name__, ex.args)
    print message

作る 確実 message は、見逃しにくい方法でユーザーの注意を喚起します! 上記のように印刷しても、メッセージが他の多くのメッセージに埋もれてしまっては、十分とは言えません。ユーザーの注意を引かないということは、すべての例外を飲み込んでしまうことと同じです。このページの回答を読んで、あなたが抱くべき印象があるとすれば、それは、これは 良いことではない . exceptブロックの最後を raise 文は、捕捉した例外を透過的に再発生させることで問題を解決します。

上記と、単に except: 引数なしは2つあります。

  • 裸の except: では、検査するための例外オブジェクトは得られません。
  • 例外処理 SystemExit , KeyboardInterruptGeneratorExit は上記のコードに引っかからないので、一般に望むところでしょう。一般に、これは望ましいことです。 例外の階層 .

例外をキャッチしなかった場合のスタックトレースも欲しい場合は、次のようにします (やはり except 節の中です)。

import traceback
print traceback.format_exc()

を使用する場合は logging モジュールを使用すると、次のようにログに例外を(メッセージとともに)出力することができます。

import logging
log = logging.getLogger()
log.exception("Message for you, sir!")

もっと深く掘り下げて、スタックを調べたり、変数を見たりしたい場合は post_mortem の関数を使用します。 pdb モジュールの中で、exceptブロックの中で

import pdb
pdb.post_mortem()

この方法は、バグを発見するのに非常に有効な方法です。