it-swarm.com.de

Wie werden Ausnahmen richtig ignoriert?

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
650
Joan Venge
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:

904
vartec

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.

124
dbr

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
108
Jason Baker

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
72
Jabba

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
54
cbare

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.

Spezifisch für das Beispiel:

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.

Allgemeiner Ansatz

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.

Neu in Python 3.4:

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:

Python 2 & 3:

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 
40
Aaron Hall

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. 

9

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()
0
citynorman