414 Stimmen

Warum ist "außer: pass" eine schlechte Programmierpraxis?

Ich sehe oft Kommentare zu anderen Stack Overflow Fragen, die darauf hinweisen, dass die Verwendung von except: pass nicht empfohlen wird. Warum ist das schlecht? Manchmal ist es mir einfach egal, welche Fehler auftreten und ich möchte einfach nur den Code weiter ausführen.

try:
    something
except:
    pass

Warum ist es schlecht, einen except: pass Block zu verwenden? Was macht es schlecht? Liegt es daran, dass ich einen Fehler einfach ignoriere oder dass ich jeglichen Fehler abfange?

282voto

Aaron Digulla Punkte 308693

Das Hauptproblem hier ist, dass es alle Fehler ignoriert: Aus Speichermangel, Überhitzung der CPU, Benutzer möchte stoppen, Programm möchte beenden, Jabberwocky tötet Benutzer.

Das ist viel zu viel. In deinem Kopf denkst du "Ich möchte diesen Netzwerkfehler ignorieren". Wenn etwas unerwartetes schief geht, dann fährt dein Code stillschweigend fort und bricht auf vollkommen unvorhersehbare Weise zusammen, die niemand debuggen kann.

Deshalb sollte man sich darauf beschränken, nur bestimmte Fehler zu ignorieren und den Rest passieren zu lassen.

91voto

YS-L Punkte 14498

Führen Sie Ihren Pseudocode wortwörtlich aus, es wird nicht einmal ein Fehler angezeigt:

try:
    etwas
except:
    pass

Als ob es sich um ein vollkommen gültiges Stück Code handelt, anstatt einen NameError zu werfen. Ich hoffe, das ist nicht, was Sie wollen.

61voto

Warum ist "except: pass" eine schlechte Programmierpraxis?

Warum ist das schlecht?

try:
    something
except:
    pass

Dies erfasst jede mögliche Ausnahme, einschließlich GeneratorExit, KeyboardInterrupt und SystemExit - Ausnahmen, die Sie wahrscheinlich nicht beabsichtigen zu erfassen. Es ist das Gleiche wie das Fangen von BaseException.

try:
    something
except BaseException:
    pass

Ältere Versionen der Dokumentation sagen:

Da in Python jeder Fehler eine Ausnahme auslöst, kann die Verwendung von except: viele Programmfehler wie Laufzeitprobleme aussehen lassen, was den Debugging-Prozess behindert.

Python Ausnahme Hierarchie

Wenn Sie eine übergeordnete Ausnahmeklasse abfangen, fangen Sie auch alle ihre Unterklassen ab. Es ist viel eleganter, nur die Ausnahmen abzufangen, für die Sie vorbereitet sind.

Hier ist die Python 3 Ausnahme-Hierarchie - wollen Sie wirklich alle einfangen?:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

Das hier nicht tun

Wenn Sie diese Form des Exception-Handlings verwenden:

try:
    something
except: # fangen Sie nicht einfach alles ab!
    pass

Dann können Sie Ihren something Block nicht mit Strg-C unterbrechen. Ihr Programm wird jede mögliche Ausnahme im try Codeblock übersehen.

Hier ist ein weiteres Beispiel, das das gleiche unerwünschte Verhalten haben wird:

except BaseException as e: # machen Sie das auch nicht - dasselbe wie oben!
    logging.info(e)

Versuchen Sie stattdessen, nur die spezifische Ausnahme abzufangen, von der Sie wissen, dass Sie sie suchen. Wenn Sie beispielsweise wissen, dass Sie möglicherweise einen Wertefehler bei einer Konvertierung erhalten:

try:
    foo = operation_that_includes_int(foo)
except ValueError as e:
    if fatal_condition(): # Sie können die Ausnahme auslösen, wenn sie schlecht ist,
        logging.info(e)   # aber wenn es jedes Mal fatal ist,
        raise             # sollten Sie es wahrscheinlich einfach nicht abfangen.
    else:                 # Fange nur die Ausnahmen ab, für die du vorbereitet bist.
        foo = 0           # Hier weisen wir einfach foo den Wert 0 zu und fahren fort.

Weitere Erklärung mit einem anderen Beispiel

Sie könnten dies tun, weil Sie zum Beispiel beim Web-Scraping einen UnicodeError erhalten haben, aber weil Sie das breiteste Ausnahmefangen verwendet haben, wird Ihr Code, der möglicherweise andere grundlegende Fehler hat, versuchen, bis zum Abschluss ausgeführt zu werden, wodurch Bandbreite verschwendet wird, Bearbeitungszeit, Verschleiß an Ihrer Ausrüstung, Speicherplatz, Sammeln von falschen Daten, usw.

Wenn andere Personen von Ihnen verlangen, dass Sie abschließen, damit sie sich auf Ihren Code verlassen können, verstehe ich, dass Sie sich verpflichtet fühlen könnten, einfach alles zu behandeln. Aber wenn Sie bereit sind, während der Entwicklung laut zu scheitern, haben Sie die Möglichkeit, Probleme zu korrigieren, die möglicherweise nur gelegentlich auftreten, aber langfristig kostspielige Fehler wären.

Mit präziserer Fehlerbehandlung kann Ihr Code robuster sein.

31voto

Booster Punkte 1650
>>> import this

The Zen of Python, by Tim Peters

Schön ist besser als hässlich.
Explizit ist besser als implizit.
Einfach ist besser als komplex.
Komplex ist besser als kompliziert.
Flach ist besser als verschachtelt.
Großzügig ist besser als dicht.
Lesbarkeit zählt.
Spezialfälle sind nicht speziell genug, um die Regeln zu brechen.
Obwohl Pragmatismus Ehrlichkeit schlägt.
Fehler sollten niemals stillschweigend passieren.
Es sei denn, sie werden explizit zum Schweigen gebracht.
Angesichts von Mehrdeutigkeiten, widerstehen Sie der Versuchung zu raten.
Es sollte einen -- und vorzugsweise nur einen -- offensichtlichen Weg geben, es zu tun.
Obwohl dieser Weg am Anfang nicht offensichtlich sein kann, es sei denn, du bist Niederländisch.
Jetzt ist besser als nie.
Obwohl nie oft besser ist als jetzt.
Wenn die Implementierung schwer zu erklären ist, ist es eine schlechte Idee.
Wenn die Implementierung leicht zu erklären ist, könnte es eine gute Idee sein.
Namensräume sind eine großartige Idee - lasst uns mehr davon machen!

Also, hier ist meine Meinung. Immer wenn Sie einen Fehler finden, sollten Sie etwas tun, um ihn zu behandeln, z.B. in eine Protokolldatei schreiben oder etwas anderes. Zumindest informiert es Sie, dass es einmal einen Fehler gab.

27voto

Tupteq Punkte 2768

Sie sollten mindestens except Exception: verwenden, um das Abfangen von Systemausnahmen wie SystemExit oder KeyboardInterrupt zu vermeiden. Hier ist ein Link zur Dokumentation.

Im Allgemeinen sollten Sie ausdrücklich die Ausnahmen definieren, die Sie abfangen möchten, um das Abfangen unerwünschter Ausnahmen zu vermeiden. Sie sollten wissen, welche Ausnahmen Sie ignorieren.

CodeJaeger.com

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.

Powered by:

X