Wie erhalte ich den Namen der Ausnahme, die in Python abgefangen wurde?

122

Wie kann ich den Namen einer Ausnahme ermitteln, die in Python ausgelöst wurde?

z.B,

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

Zum Beispiel fange ich mehrere (oder alle) Ausnahmen ab und möchte den Namen der Ausnahme in einer Fehlermeldung drucken.

Rob Bednark
quelle
3
Warum denkst du, brauchst du das? Warum nicht gleich eine konkretere Ausnahme (z. B. except NameError:) einfangen ?
7
Ich habe einige Szenarien, in denen ich alle Ausnahmen (oder eine Liste davon) abfangen und den Namen der Ausnahme in einer Fehlermeldung ausdrucken möchte.
Rob Bednark
1
Vielleicht möchten Sie das tracebackModul der Standardbibliothek ausprobieren, das Funktionen enthält, mit denen Ausnahmen und Rückverfolgungen gut formatiert werden können.
Blckknght
1
@delnan diese Situation tritt auf, wenn Sie testen, ob eine Funktion eine Ausnahme wie programmiert
auslöst
Ich brauchte so etwas, um Code auszutrocknen: Mit der von mir aufgerufenen Methode können mehrere Ausnahmen ausgelöst werden. Jede Ausnahme wird mit einer eigenen exceptAnweisung behandelt, aber der Protokolleintrag ist in jedem Fall sehr ähnlich.
Adam Carroll

Antworten:

223

Es gibt verschiedene Möglichkeiten, um den Namen der Klasse der Ausnahme abzurufen:

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

z.B,

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

Das funktioniert, aber es scheint, dass es einen einfacheren und direkteren Weg geben muss?

try:
    foo = bar
except Exception as exception:
    assert repr(exception) == '''NameError("name 'bar' is not defined",)'''
    name = repr(exception).split('(')[0]
    assert name == 'NameError'
Rob Bednark
quelle
4
Ersetzen Sie except Exception as exceptiondurch die Art der Ausnahme, die Sie abfangen möchten, z except NameError as exception.
Maciej Gol
8
Ich möchte keine im Voraus bekannten Ausnahmen abfangen. Ich möchte alle Ausnahmen abfangen .
Rob Bednark
3

Sie können auch verwenden sys.exc_info(). exc_info()gibt 3 Werte zurück: Typ, Wert, Rückverfolgung. Zur Dokumentation: 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__
Moshfiqur
quelle
1

Wenn Sie den vollständig qualifizierten Klassennamen möchten (z. B. sqlalchemy.exc.IntegrityErrorstatt nur IntegrityError), können Sie die folgende Funktion verwenden, die ich aus MBs großartiger Antwort auf eine andere Frage übernommen habe (ich habe nur einige Variablen umbenannt, um sie meinem Geschmack anzupassen):

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__

Beispiel:

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

# sqlalchemy.exc.IntegrityError
MarredCheese
quelle
0

Die anderen Antworten hier eignen sich hervorragend für Erkundungszwecke. Wenn das Hauptziel jedoch darin besteht, die Ausnahme (einschließlich des Namens der Ausnahme) zu protokollieren, sollten Sie möglicherweise logging.exception anstelle von print verwenden.

MrName
quelle