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?

6voto

Panzercrisis Punkte 4435

Einfach ausgedrückt, wenn eine Ausnahme oder ein Fehler auftritt, stimmt etwas nicht. Es muss nicht unbedingt etwas sehr falsch sein, aber das Erstellen, Auslösen und Abfangen von Fehlern und Ausnahmen nur um Goto-Anweisungen zu verwenden, ist keine gute Idee und wird selten gemacht. 99% der Zeit gab es irgendwo ein Problem.

Probleme müssen angegangen werden. So wie im Leben, in der Programmierung, wenn man Probleme einfach ignoriert und versucht, sie zu umgehen, verschwinden sie oft nicht einfach von selbst; stattdessen werden sie größer und vermehren sich. Um zu verhindern, dass ein Problem auf Sie zukommt und später erneut zuschlägt, müssen Sie entweder 1) es beseitigen und anschließend aufräumen oder 2) es eindämmen und anschließend aufräumen.

Ausnahmen und Fehler einfach zu ignorieren und sie so stehen zu lassen, ist ein guter Weg, um Speicherlecks, offene Datenbankverbindungen, unnötige Sperren für Dateiberechtigungen usw. zu erleben.

In seltenen Fällen ist das Problem so winzig, trivial und - abgesehen von der Notwendigkeit eines try...catch-Blocks - selbständig, dass es wirklich keine Aufräumarbeiten danach gibt. Dies sind die einzigen Gelegenheiten, in denen diese bewährte Praxis nicht unbedingt zutrifft. Meiner Erfahrung nach bedeutet dies im Allgemeinen, dass was auch immer der Code tut, im Grunde genommen belanglos und verzichtbar ist, und etwas wie Wiederholungsversuche oder spezielle Nachrichten weder die Komplexität noch das Anhalten des Threads wert sind.

In meinem Unternehmen gilt die Regel, fast immer etwas in einem Catch-Block zu tun, und wenn Sie nichts tun, müssen Sie immer einen Kommentar mit einem sehr guten Grund dafür abgeben. Sie dürfen niemals einen leeren Catch-Block passieren lassen, wenn noch etwas zu tun ist.

6voto

Sirac Punkte 693

In meiner Meinung haben Fehler einen Grund, warum sie auftreten, das mag dumm klingen, aber so ist es. Gutes Programmieren erzeugt nur Fehler, wenn du sie behandeln musst. Außerdem, wie ich vor einiger Zeit gelesen habe, ist "die pass-Anweisung eine Anweisung, die zeigt, dass Code später eingefügt wird", also wenn du eine leere except-Anweisung haben möchtest, dann fühle dich frei, dies zu tun, aber für ein gutes Programm wird ein Teil fehlen, da du die Dinge, die du haben solltest, nicht behandelt hast. Auftretende Ausnahmen geben dir die Möglichkeit, Eingabedaten zu korrigieren oder deine Datenstruktur zu ändern, sodass diese Ausnahmen nicht erneut auftreten (aber in den meisten Fällen (Netzwerk-Ausnahmen, allgemeine Eingabe-Ausnahmen) weisen Ausnahmen darauf hin, dass die nächsten Teile des Programms nicht gut ausgeführt werden. Zum Beispiel kann eine Netzwerk-Ausnahme auf eine unterbrochene Netzwerkverbindung hinweisen und das Programm kann in den nächsten Programmabschnitten keine Daten senden/empfangen.

Aber das Verwenden eines pass-Blocks nur für einen Ausnahme-Block ist zulässig, da du weiterhin zwischen den Arten von Ausnahmen unterscheidest, also wenn du alle Ausnahme-Blöcke zusammenfügst, ist er nicht leer:

try:
    #Code hier
except Fehler1:
    #Ausnahmebehandlung1

except Fehler2:
    #Ausnahmebehandlung2
#und so weiter

kann auch umgeschrieben werden:

try:
    #Code hier
except BaseException as e:
    if isinstance(e, Fehler1):
        #Ausnahmebehandlung1

    elif isinstance(e, Fehler2):
        #Ausnahmebehandlung2

    ...

    else:
        raise

Selbst mehrere except-Blöcke mit pass-Anweisungen können also in Code resultieren, dessen Struktur spezielle Arten von Ausnahmen behandelt.

6voto

galets Punkte 16843

Alle bisherigen Kommentare sind gültig. Wo möglich, müssen Sie angeben, welche Ausnahme genau Sie ignorieren möchten. Wo möglich, müssen Sie analysieren, was die Ausnahme verursacht hat, und nur ignorieren, was Sie ignorieren wollten, und nicht den Rest. Wenn eine Ausnahme dazu führt, dass die Anwendung "spektakulär abstürzt", dann sei es so, denn es ist viel wichtiger zu wissen, dass das Unerwartete passiert ist, als zu verbergen, dass das Problem überhaupt aufgetreten ist.

Bei all dem sollten Sie keine Programmierpraxis als maßgeblich betrachten. Das ist dumm. Es gibt immer Zeit und Ort für einen "alle Ausnahmen ignorieren"-Block.

Ein weiteres Beispiel für idiotische Überhöhung ist die Verwendung des goto-Operators. Als ich in der Schule war, hat unser Professor uns den goto-Operator gelehrt, nur um zu erwähnen, dass man ihn NIEMALS verwenden soll. Glauben Sie nicht den Leuten, die Ihnen sagen, dass xyz nie verwendet werden sollte und es keine Szenarien gibt, in denen es nützlich ist. Es gibt immer welche.

3voto

Mateen Ulhaq Punkte 21111

Da es noch nicht erwähnt wurde, ist es besserer Stil, contextlib.suppress zu verwenden:

with suppress(FileNotFoundError):
    os.remove('somefile.tmp')

In diesem Beispiel wird die Datei somefile.tmp nach Ausführung dieses Codeblocks nicht vorhanden sein, ohne dass Ausnahmen ausgelöst werden (außer FileNotFoundError, der unterdrückt wird).

2voto

fastcodejava Punkte 37539

Die Behandlung von Fehlern ist in der Programmierung sehr wichtig. Du musst dem Benutzer zeigen, was schief gelaufen ist. In sehr wenigen Fällen kannst du die Fehler ignorieren. Das ist eine sehr schlechte Programmierpraxis.

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