Python: Wie man eine Ausnahme ignoriert und fortfährt?


239

Ich habe einen Versuch ... außer Block in meinem Code und wenn eine Ausnahme geworfen wird. Ich möchte wirklich nur mit dem Code fortfahren, weil in diesem Fall alles noch gut läuft. Das Problem ist, wenn Sie den Block "except:" leer lassen oder mit einem # do nothing, erhalten Sie einen Syntaxfehler. Ich kann nicht fortfahren, weil es nicht in einer Schleife ist. Gibt es ein Schlüsselwort, das ich verwenden kann, sagt der Code, um einfach weiterzumachen?

359
except: 
    pass 
+64

außer Ausnahme: Pass # wichtig, andere Ausnahmen nicht zu schlucken! 22 feb. 092009-02-22 16:46:45

+8

@Aaron - Ich stimme zu, aber die Frage war nicht, ob das eine gute/schlechte Idee war 23 feb. 092009-02-23 20:05:24

+15

Dies wird SystemExit, KeyboardInterrupt und andere Dinge fangen, die Sie wahrscheinlich nicht fangen wollen. 02 jan. 102010-01-02 01:13:31

+1

Es wird KeyboardInterrupt nicht abfangen. Zum Beispiel: 'while True:' ' versuchen: ' f = open ('filedoesnotexist.txt') '' Ausnahme: '' pass' KeyboardInterrupt den Code anhält und schließt. 24 jul. 122012-07-24 15:59:51

+14

@ChthonicProject Ein blankes 'except' wird alle Exceptions fangen, einschließlich eines KeyboardInterrupt, aber nur wenn es innerhalb des' try' passiert. In Ihrem Beispiel kann ein KeyboardInterrupt vor dem "try" oder innerhalb des 'except' auftreten, wo es nicht abgefangen wird. Wenn Sie ein Beispiel wie 'while True:' 'try: pass'' except: pass' ausführen, werden Sie feststellen, dass der KeyboardInterrupt nur etwa 50% der Zeit gefangen wird. Wenn Sie 'time.sleep (1)' innerhalb des 'try's finden, werden Sie feststellen, dass es fast jedes Mal gefangen wird. 22 mär. 132013-03-22 08:39:50


12

Try this:

try: 
    blah() 
except: 
    pass 

202

Der Standard "nop" in Python ist die pass Aussage:

try: 
    do_something() 
except Exception: 
    pass 

Wegen der zuletzt ausgelösten Exception in Python erinnert werden, einige der Objekte, die an der Exception-throwing-Anweisung beteiligt sind, werden auf unbestimmte Zeit live gehalten (eigentlich bis zur nächsten Ausnahme). Falls dies für Sie wichtig und (in der Regel), die Sie brauchen, um die letzte ausgelöste Ausnahme nicht mehr zu erinnern, könnten Sie das folgende statt pass tun wollen:

try: 
    do_something() 
except Exception: 
    sys.exc_clear() 

Dies löscht die letzte geworfen Ausnahme.

+26

Dies ist eine bessere Antwort als die, die akzeptiert wurde, weil sie "except Exception:" anstatt nur "except:" verwendet, was andere, wie andere darauf hingewiesen haben, nicht wie SystemExit und KeyboardInterrupt fangen . 11 jul. 112011-07-11 21:50:28

+4

+1 Es löscht auch den Fehler, der beim Ausführen von Unittests wichtig ist und Ausnahmen erwartet 26 okt. 112011-10-26 13:50:55

  0

Beachten Sie, dass 'exc_clear' in Python 3 entfernt wurde. Https: // docs.python.org/3/whatsnew/3.0.html#index-22. Für einige Möglichkeiten, dies in Python 3 zu beheben, siehe hier: https://cosmicpercolator.com/2016/01/13/exception-leaks-in-python-2-and-3/ 06 mär. 182018-03-06 18:59:18


114

Es gibt einen neuen Weg, dies in Python kommt zu tun 3.4:

from contextlib import suppress 

with suppress(Exception): 
    # your code 

Hier ist die commit, dass hinzugefügt, um es: http://hg.python.org/cpython/rev/406b47c64480

Und hier ist der Autor, Raymond Hettinger, im Gespräch über diese und alle Arten von andere Python hotness (relevant Bit bei 43:30): http://www.youtube.com/watch?v=OSGv2VnC0go

Wenn Sie das blanke except Schlüsselwort und auch ignorieren Dinge wie KeyboardInterrupt -though Sie in der Regel dont-man konnte emulieren wollte Verwenden Sie with suppress(BaseException).

Bearbeiten: Sieht aus wie ignored wurde vor der Version 3.4 in suppress umbenannt.

+1

Ich bin mir nicht sicher, ob mir diese Lösung gefällt ... Ich denke, die Idee ist, wir haben 3 Zeilen durch nur 1 ersetzt (der Versuch, außer, und Pass sind alle zu einem verschmolzen.) Die Hauptsache, die ich ablehne, ist wie ein neues Schlüsselwort eingeführt wird, das etwas zu rechtfertigen scheint Sie sollten wahrscheinlich nicht tun ... es scheint, als ob Sie immer mindestens Ausnahmen protokollieren sollten Sie fangen ... 14 okt. 132013-10-14 13:13:09

  0

Wenn eine Ausnahme ausgelöst wird, wird es den Code nach dem Versuch/fangen oder was auch immer außerhalb der ' mit 'Block? 13 nov. 132013-11-13 07:45:05

+1

Dies entspricht dem Wrapping Ihres Codes in einem 'try ... catch: pass'. Wenn also innerhalb des Blocks eine Ausnahme ausgelöst wird, wird die Ausführung nach dem Ende der Blockierung fortgesetzt. 14 nov. 132013-11-14 08:45:10

+4

@ JackO'Connor Nun, das macht es ziemlich nutzlos ... Ich dachte, es würde Ausnahmen einfach ignorieren, wie versprochen. 04 dez. 132013-12-04 20:21:50

+2

@ArtOfWarfare Was ist, wenn ich sagte, ich gebe dir eine ganze Zahl, aber manchmal gebe ich es dir in einem Singleton-Tupel, und ich werde es dir nicht sagen, wenn ich das eine oder andere mache; Jetzt ist es deine Aufgabe, mir immer die ganze Zahl zurückzugeben? Vielleicht würdest du es schätzen, etwas schreiben zu können wie 'with suppress (TypeError): return data [0]' (längeres Beispiel: http://pastebin.com/gcvAGqEP) 02 mai. 142014-05-02 21:03:25

  0

@Navin Python kann nicht einfach so tun, als ob eine Ausnahme aufgetreten wäre Ich existiere nicht. Angenommen, ich habe eine Aussage wie y = f (x) * g (x) ', und dann löst f (x) eine Ausnahme aus. Selbst wenn Python es ignoriert, gibt 'f (x)' niemals einen Wert zurück, also gibt es für Python keine Möglichkeit, y 'einen Wert zuzuweisen. Die Designer hätten sagen können: "Nehme einen Wert von None" oder "Überspringe Anweisungen, die Ausdrücke enthalten, die nicht ausgewertet werden konnten", aber das würde am Ende sehr verwirrend sein. Die Verwendung von "try" -Blöcken zum Gruppieren von Anweisungen, die zusammen versagen, hält die Dinge einfach. 14 jan. 152015-01-14 17:14:23

  0

@ JackO'Connor Fair genug. Ich hatte gehofft, dass es einen Weg geben würde, einen Ausdruck durch None zu ersetzen, wenn er eine Ausnahme auslöst. 14 jan. 152015-01-14 18:07:12

  0

Kann es inline gemacht werden? Zum Beispiel so etwas wie 'supress (myFunc, supportedException, returnValueOnFailure)' '? 23 jun. 152015-06-23 01:43:01

  0

@JeromeJ Sie können das nicht direkt mit 'suppress' machen, weil es ein Kontextmanager ist. (Einzelheiten zur Funktionsweise von Kontext-Managern finden Sie hier: https://docs.python.org/3.4/library/stdtypes.html#typecontextmanager). Es wäre jedoch ziemlich einfach, eine eigene 'callCatchingExceptions'-Funktion zu definieren, die 'suppress' verwendet 'oder ein gewöhnlicher' Versuch' Block auf der Innenseite, wenn Sie wollten. 24 jun. 152015-06-24 14:01:27

+1

FYI, django kehrt die Verwendung von 'with suppress (Exception)' auf 2017-09 zurück, weil try/except besser funktioniert. Überprüfe diese Commits [Reverted "Fixed # 27818 - Ersetze try/except/pass mit contextlib.su ...] (https://github.com/django/django/commit/6e4c6281dbb7ee12bcdc22620894edb4e9cf623f) 07 nov. 172017-11-07 07:00:17