some_function()
während der Ausführung eine Ausnahme auslöst, springt das Programm zur except
:
try:
some_function()
except:
print("exception happened!")
Wie erkenne ich die Ursache für das Auftreten der Ausnahme?
some_function()
während der Ausführung eine Ausnahme auslöst, springt das Programm zur except
:
try:
some_function()
except:
print("exception happened!")
Wie erkenne ich die Ursache für das Auftreten der Ausnahme?
Die anderen Antworten weisen alle darauf hin, dass man keine generischen Ausnahmen erwischen sollte, aber niemand scheint Ihnen sagen zu wollen, warum, was wichtig ist, um zu verstehen, wann man die "Regel" brechen kann. Hier ist eine Erklärung. Im Grunde ist es so, dass man sich nicht verstecken muss:
Solange Sie also darauf achten, nichts davon zu tun, ist es in Ordnung, die generische Ausnahme abzufangen. Sie könnten dem Benutzer beispielsweise auf andere Weise Informationen über die Ausnahme zur Verfügung stellen, etwa so:
Wie kann man also die allgemeine Ausnahme abfangen? Es gibt mehrere Möglichkeiten. Wenn Sie nur das Ausnahmeobjekt haben wollen, gehen Sie wie folgt vor:
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
Machen Sie sicher message
wird dem Nutzer auf eine unübersehbare Weise nahegebracht! Es reicht nicht aus, sie wie oben gezeigt auszudrucken, wenn die Meldung unter vielen anderen Meldungen vergraben ist. Die Aufmerksamkeit des Benutzers nicht zu erregen, ist gleichbedeutend damit, alle Ausnahmen zu schlucken, und wenn es einen Eindruck gibt, den Sie nach dem Lesen der Antworten auf dieser Seite gewonnen haben sollten, dann ist es, dass dies keine gute Sache . Beenden Sie den except-Block mit einem raise
Anweisung behebt das Problem, indem sie die abgefangene Ausnahme transparent wieder aufruft.
Der Unterschied zwischen der obigen Vorgehensweise und der alleinigen Verwendung von except:
ohne jedes Argument ist zweifach:
except:
gibt Ihnen das Ausnahmeobjekt nicht zur PrüfungSystemExit
, KeyboardInterrupt
y GeneratorExit
werden von dem obigen Code nicht erfasst, was im Allgemeinen erwünscht ist. Siehe die Ausnahmehierarchie .Wenn Sie auch die gleiche Stacktrace, die Sie erhalten, wenn Sie nicht fangen die Ausnahme, können Sie, dass wie folgt (immer noch innerhalb der except-Klausel) erhalten:
import traceback
print traceback.format_exc()
Wenn Sie die logging
Modul können Sie die Ausnahme (zusammen mit einer Meldung) wie folgt in das Protokoll ausgeben:
import logging
log = logging.getLogger()
log.exception("Message for you, sir!")
Wenn Sie tiefer graben und den Stack untersuchen wollen, sich Variablen usw. ansehen wollen, verwenden Sie die post_mortem
Funktion der pdb
Modul innerhalb des Except-Blocks:
import pdb
pdb.post_mortem()
Ich habe festgestellt, dass diese letzte Methode bei der Suche nach Fehlern von unschätzbarem Wert ist.
Ermittelt den Namen der Klasse, zu der das Ausnahmeobjekt gehört:
e.__class__.__name__
und mit der Funktion print_exc() wird auch der Stack-Trace ausgegeben, der eine wichtige Information für jede Fehlermeldung ist.
Zum Beispiel so:
from traceback import print_exc
class CustomException(Exception): pass
try:
raise CustomException("hi")
except Exception as e:
print ('type is:', e.__class__.__name__)
print_exc()
# print("exception happened!")
Sie erhalten dann eine Ausgabe wie diese:
type is: CustomException
Traceback (most recent call last):
File "exc.py", line 7, in <module>
raise CustomException("hi")
CustomException: hi
Und nach dem Ausdruck und der Analyse kann der Code entscheiden, die Ausnahme nicht zu behandeln und einfach auszuführen raise
:
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except CustomException as e:
# here do some extra steps in case of CustomException
print('custom logic doing cleanup and more')
# then re raise same exception
raise
Ausgabe:
custom logic doing cleanup and more
Und der Interpreter gibt eine Ausnahme aus:
Traceback (most recent call last):
File "test.py", line 9, in <module>
calculate()
File "test.py", line 6, in calculate
raise CustomException("hi")
__main__.CustomException: hi
Nach raise
Die ursprüngliche Ausnahme breitet sich weiter auf dem Aufrufstapel aus. ( Vorsicht vor möglichen Fallstricken ) Wenn Sie eine neue Ausnahme auslösen, wird ein neuer (kürzerer) Stacktrace erstellt.
from traceback import print_exc
class CustomException(Exception):
def __init__(self, ok):
self.ok = ok
def calculate():
raise CustomException(False)
try:
calculate()
except CustomException as e:
if not e.ok:
# Always use `raise` to rethrow exception
# following is usually mistake, but here we want to stress this point
raise CustomException(e.ok)
print("handling exception")
Ausgabe:
Traceback (most recent call last):
File "test.py", line 13, in <module>
raise CustomException(e.message)
__main__.CustomException: hi
Beachten Sie, dass Traceback nicht die calculate()
Funktion ab Zeile 9
die der Ursprung der ursprünglichen Ausnahme ist e
.
Normalerweise sollten Sie nicht alle möglichen Ausnahmen mit try: ... except
da dies zu weit gefasst ist. Nehmen Sie nur die Fälle auf, die aus irgendeinem Grund zu erwarten sind. Wenn Sie wirklich müssen, zum Beispiel wenn Sie während der Fehlersuche mehr über ein Problem herausfinden wollen, sollten Sie Folgendes tun
try:
...
except Exception as ex:
print ex # do whatever you want for debugging.
raise # re-raise exception.
Die meisten Antworten verweisen auf except (…) as (…):
Syntax (zu Recht), aber gleichzeitig will niemand über den Elefanten im Raum sprechen, der der Elefant ist sys.exc_info()
Funktion. Von der Dokumentation de sys Modul (Hervorhebung von mir):
Diese Funktion gibt ein Tupel von drei Werten zurück, die Informationen liefern über die Ausnahme, die gerade behandelt wird.
( )
Wenn nirgendwo auf dem Stapel eine Ausnahme behandelt wird, wird ein Tupel zurückgegeben, das drei None-Werte enthält. Andernfalls werden die Werte zurückgegeben (Typ, Wert, Traceback). Ihre Bedeutung ist: t Typ der zu behandelnden Ausnahme (eine Unterklasse von BaseException); value liefert die Instanz der Ausnahme (eine Instanz des Ausnahmetyps); traceback liefert ein Traceback-Objekt (siehe das Referenzhandbuch), das den Aufrufstapel an dem Punkt kapselt, an dem die Ausnahme ursprünglich aufgetreten ist.
Ich denke, die sys.exc_info()
könnte als die direkteste Antwort auf die ursprüngliche Frage behandelt werden Woher weiß ich, welche Art von Ausnahme aufgetreten ist?
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.