Pythonでキャッチされた例外の名前を取得するにはどうすればよいですか?


122

Pythonで発生した例外の名前を取得するにはどうすればよいですか?

例えば、

try:
    foo = bar
except Exception as exception:
    name_of_exception = ???
    assert name_of_exception == 'NameError'
    print "Failed with exception [%s]" % name_of_exception

たとえば、複数(またはすべて)の例外をキャッチしていて、その例外の名前をエラーメッセージに出力したいと考えています。


3
なぜこれが必要だと思いますか?except NameError:はじめに、より具体的な例外(例:)をキャッチしませんか?

7
すべての例外(またはそれらのリスト)をキャッチし、例外の名前をエラーメッセージに出力するシナリオがいくつかあります。
Rob Bednark 2013

1
traceback例外とトレースバックの優れたフォーマットを行う関数を備えた標準ライブラリのモジュールをチェックアウトすることもできます。
Blckknght 2014年

1
@delnanこの状況は、関数がプログラムされた
とおりに

私はいくつかのコードを乾燥させるためにこのようなものが必要でした:私が呼び出しているメソッドによっていくつかの例外が発生する可能性があり、それぞれが独自のexceptステートメントで処理されますが、ログエントリはそれぞれ非常に似ています。
Adam Carroll

回答:


223

例外のクラスの名前を取得するには、いくつかの方法があります。

  1. type(exception).__name__
  2. exception.__class__.__name__
  3. exception.__class__.__qualname__

例えば、

try:
    foo = bar
except Exception as exception:
    assert type(exception).__name__ == 'NameError'
    assert exception.__class__.__name__ == 'NameError'
    assert exception.__class__.__qualname__ == 'NameError'

6

これは機能しますが、もっと簡単で直接的な方法があるはずです?

try:
    foo = bar
except Exception as exception:
    assert repr(exception) == '''NameError("name 'bar' is not defined",)'''
    name = repr(exception).split('(')[0]
    assert name == 'NameError'

4
except Exception as exceptionキャッチする例外のタイプ、つまりに置き換えますexcept NameError as exception
Maciej Gol

8
事前にわかっている特定の例外をキャッチしたくありません。すべての例外をキャッチたい。
Rob Bednark、2018

3

も使用できますsys.exc_info()exc_info()タイプ、値、トレースバックの3つの値を返します。ドキュメント:https : //docs.python.org/3/library/sys.html#sys.exc_info

import sys

try:
    foo = bar
except Exception:
    exc_type, value, traceback = sys.exc_info()
    assert exc_type.__name__ == 'NameError'
    print "Failed with exception [%s]" % exc_type.__name__

1

完全修飾クラス名が必要な場合(たとえばsqlalchemy.exc.IntegrityErrorだけではなくIntegrityError)、以下の関数を使用できます。これは、MBの素晴らしい答えから別の質問に取り入れました(好みに合わせていくつかの変数の名前を変更しました)。

def get_full_class_name(obj):
    module = obj.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return obj.__class__.__name__
    return module + '.' + obj.__class__.__name__

例:

try:
    # <do something with sqlalchemy that angers the database>
except sqlalchemy.exc.SQLAlchemyError as e:
    print(get_full_class_name(e))

# sqlalchemy.exc.IntegrityError

0

ここでの他の回答は探索目的には最適ですが、主な目的が例外を記録することである場合(例外の名前を含む)、おそらくprintではなくlogging.exceptionの使用を検討しますか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.