Wenn Sie nur einen try-except ausführen möchten, ohne die Ausnahme zu behandeln, wie machen Sie das in Python?
Ist der folgende Weg der richtige Weg?
try:
shutil.rmtree(path)
except:
pass
try:
doSomething()
except:
pass
oder
try:
doSomething()
except Exception:
pass
Der Unterschied ist, dass der erste auch KeyboardInterrupt
, SystemExit
und solche Sachen fängt, die direkt von exceptions.BaseException
und nicht von exceptions.Exception
abgeleitet sind.
Weitere Informationen finden Sie in der Dokumentation:
Im Allgemeinen gilt es als Best-Practice, nur die Fehler zu finden, an denen Sie interessiert sind. Im Fall von shutil.rmtree
ist dies wahrscheinlich OSError
:
>>> shutil.rmtree("/fake/dir")
Traceback (most recent call last):
[...]
OSError: [Errno 2] No such file or directory: '/fake/dir'
Wenn Sie diesen Fehler ignorieren möchten, tun Sie Folgendes:
try:
shutil.rmtree(path)
except OSError:
pass
Warum? Angenommen, Sie übergeben (irgendwie) aus Versehen der Funktion eine ganze Zahl anstelle einer Zeichenfolge, wie:
shutil.rmtree(2)
Es wird der Fehler "TypeError: zu Unicode zwingend: Zeichenfolge oder Puffer benötigt, int gefunden".
Wenn Sie definitiv alle Fehler ignorieren möchten, müssen Sie Exception
und keine bloße except:
-Anweisung verwenden. Warum wieder?
Wenn Sie keine Ausnahme angeben, wird jede -Ausnahme abgefangen, einschließlich der Ausnahme SystemExit
, die beispielsweise sys.exit()
verwendet:
>>> try:
... sys.exit(1)
... except:
... pass
...
>>>
Vergleichen Sie dies mit dem folgenden, das korrekt ausgeführt wird:
>>> try:
... sys.exit(1)
... except Exception:
... pass
...
Shell:~$
Wenn Sie Code schreiben möchten, der sich besser verhält, kann die Ausnahme OSError
verschiedene Fehler darstellen. Im obigen Beispiel möchten wir jedoch nur Errno 2
ignorieren.
try:
shutil.rmtree(path)
except OSError, e:
if e.errno == 2:
# suppress "No such file or directory" error
pass
else:
# reraise the exception, as it's an unexpected error
raise
Sie können auch import errno
und if
in if e.errno == errno.ENOENT:
ändern.
Wenn Sie nur einen Try-Catch ausführen möchten, ohne die Ausnahme zu behandeln, wie machen Sie das in Python?
Es hängt davon ab, was Sie unter "Handhabung" verstehen.
Wenn Sie beabsichtigen, ihn zu fangen, ohne etwas zu unternehmen, funktioniert der von Ihnen gepostete Code.
Wenn Sie meinen, dass Sie eine Ausnahme für die Ausnahme ergreifen möchten, ohne dass die Ausnahme den Stack erhöht, möchten Sie Folgendes:
try:
do_something()
except:
handle_exception()
raise #re-raise the exact same exception that was thrown
Zuerst zitiere ich die Antwort von Jack o'Connor aus diesem Thread . Der referenzierte Thread wurde geschlossen, deshalb schreibe ich hier:
"Es gibt einen neuen Weg, dies in Python 3.4 zu tun:
from contextlib import suppress
with suppress(Exception):
# your code
Hier ist das Commit, das es hinzugefügt hat: http://hg.python.org/cpython/rev/406b47c64480
Und hier ist der Autor, Raymond Hettinger, der über dieses und alle möglichen anderen Python-Hotness spricht: https://youtu.be/OSGv2VnC0go?t=43m23s
Meine Ergänzung dazu ist das Python 2.7-Äquivalent:
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
Dann verwenden Sie es wie in Python 3.4:
with ignored(Exception):
# your code
Zur Vollständigkeit:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print "division by zero!"
... else:
... print "result is", result
... finally:
... print "executing finally clause"
... aus dem Python-Tutorial .
Beachten Sie auch, dass Sie die Ausnahme folgendermaßen erfassen können:
>>> try:
... this_fails()
... except ZeroDivisionError as detail:
... print 'Handling run-time error:', detail
Wie werden Ausnahmen richtig ignoriert?
Dafür gibt es mehrere Möglichkeiten.
Die Wahl des Beispiels hat jedoch eine einfache Lösung, die den allgemeinen Fall nicht abdeckt.
Anstatt
try:
shutil.rmtree(path)
except:
pass
Mach das:
shutil.rmtree(path, ignore_errors=True)
Dies ist ein spezifisches Argument für shutil.rmtree
. Sie können die Hilfe dazu sehen, indem Sie die folgenden Schritte ausführen, und Sie werden sehen, dass sie auch Funktionen für Fehler zulassen kann.
>>> import shutil
>>> help(shutil.rmtree)
Da dies nur den engen Fall des Beispiels abdeckt, werde ich weiter demonstrieren, wie man damit umgeht, wenn diese Schlüsselwortargumente nicht vorhanden sind.
Da das Obige nur den engen Fall des Beispiels abdeckt, werde ich weiter demonstrieren, wie man damit umgeht, wenn diese Schlüsselwortargumente nicht vorhanden sind.
Sie können den Kontextmanager suppress
importieren:
from contextlib import suppress
Aber nur die spezifischste Ausnahme unterdrücken:
with suppress(FileNotFoundError):
shutil.rmtree(path)
Sie ignorieren still eine FileNotFoundError
:
>>> with suppress(FileNotFoundError):
... shutil.rmtree('bajkjbkdlsjfljsf')
...
>>>
Aus den docs :
Wie bei jedem anderen Mechanismus, der Ausnahmen vollständig unterdrückt, wird Dieser Kontextmanager sollte nur zur Abdeckung sehr spezifischer Fehler verwendet werden Wenn die Programmausführung im Stillen fortgesetzt wird, ist dies die Richtiges zu tun.
Beachten Sie, dass suppress
und FileNotFoundError
nur in Python 3 verfügbar sind.
Wenn Sie möchten, dass Ihr Code auch in Python 2 funktioniert, lesen Sie den nächsten Abschnitt:
Wenn Sie einfach einen Versuch/eine Ausnahme machen möchten, ohne die Ausnahme zu behandeln, Wie machst du das in Python?
Ist der folgende Weg der richtige Weg?
try : shutil.rmtree ( path ) except : pass
Für Python 2-kompatiblen Code ist pass
der richtige Weg, um eine Anweisung zu haben, die kein Operator ist. Wenn Sie jedoch einen reinen except:
ausführen, ist dies dasselbe wie das Ausführen von except BaseException:
, zu dem GeneratorExit
, KeyboardInterrupt
und SystemExit
gehören, und im Allgemeinen möchten Sie diese Dinge nicht fangen.
Tatsächlich sollten Sie die Ausnahme so genau wie möglich benennen.
Hier ist ein Teil der Python (2) Ausnahmehierarchie . Wenn Sie allgemeinere Ausnahmen abfangen, können Sie Probleme ausblenden, die Sie nicht erwartet hatten:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
... and so on
Wahrscheinlich möchten Sie hier einen OSError abfangen, und die Ausnahme, die Sie nicht interessieren, ist, wenn kein Verzeichnis vorhanden ist.
Wir können die spezifische Fehlernummer that aus der errno
-Bibliothek abrufen und reraise, wenn wir das nicht haben:
import errno
try:
shutil.rmtree(path)
except OSError as error:
if error.errno == errno.ENOENT: # no such file or directory
pass
else: # we had an OSError we didn't expect, so reraise it
raise
Beachten Sie, dass ein Bare Raise die ursprüngliche Ausnahme auslöst, was Sie in diesem Fall wahrscheinlich wollen. Kurzer geschrieben, da wir nicht unbedingt pass
mit Code in der Ausnahmebehandlung explizit benötigen:
try:
shutil.rmtree(path)
except OSError as error:
if error.errno != errno.ENOENT: # no such file or directory
raise
Wenn Sie nur einen Try-Catch ausführen möchten, ohne die Ausnahme zu behandeln, wird. Wie machst du das in Python?
Dies hilft Ihnen zu drucken, was die Ausnahme ist :( d.
import sys
try:
doSomething()
except:
print "Unexpected error:", sys.exc_info()[0]
try:
doSomething()
except Exception:
pass
else:
stuffDoneIf()
TryClauseSucceeds()
FYI Die else-Klausel kann nach allen Ausnahmen gehen und wird nur ausgeführt, wenn der Code im try keine Ausnahme verursacht.
In Python behandeln wir Ausnahmen ähnlich wie andere Sprachen, der Unterschied ist jedoch ein gewisser Unterschied in der Syntax.
try:
#Your code in which exception can occur
except <here we can put in a particular exception name>:
# We can call that exception here also, like ZeroDivisionError()
# now your code
# We can put in a finally block also
finally:
# Your code...
Ich musste Fehler in mehreren Befehlen ignorieren und fuckit machte den Trick
import fuckit
@fuckit
def helper():
print('before')
1/0
print('after1')
1/0
print('after2')
helper()