it-swarm.com.de

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

Ich sehe oft Kommentare zu anderen Stack-Overflow-Fragen, wie davon abgeraten wird, except: pass zu verwenden. Warum ist das so schlimm? Manchmal ist es mir einfach egal, was die Fehler sind, und ich möchte einfach mit dem Code fortfahren.

try:
    something
except:
    pass

Warum ist die Verwendung eines except: pass-Blocks schlecht? Was macht es schlecht? Ist es die Tatsache, dass ich pass auf einen Fehler oder except einen Fehler habe?

272
Vader

Wie Sie richtig vermutet haben, gibt es zwei Seiten: Den any-Fehler abfangen, indem Sie nach except keinen Ausnahmetyp angeben und ihn einfach übergeben, ohne etwas zu unternehmen.

Meine Erklärung ist "ein bisschen länger" - also bricht es sich ab:

  1. Nicht fangen any Fehler. Geben Sie immer an, von welchen Ausnahmen Sie sich erholen möchten, und erfassen Sie diese nur.
  2. Versuchen Sie es mit Ausnahme von Blöcken zu vermeiden. Wenn nicht ausdrücklich gewünscht, ist dies normalerweise kein gutes Zeichen.

Aber gehen wir ins Detail:

Any Fehler nicht abfangen

Wenn Sie einen try-Block verwenden, tun Sie dies normalerweise, weil Sie wissen, dass die Möglichkeit besteht, dass eine Ausnahme ausgelöst wird. Daher haben Sie auch bereits eine ungefähre Vorstellung davon, dass what brechen kann und welche Ausnahme ausgelöst werden kann. In solchen Fällen fangen Sie eine Ausnahme ab, da Sie positiv wiederherstellen von ihr abrufen können. Das bedeutet, dass Sie auf die Ausnahme vorbereitet sind und über einen alternativen Plan verfügen, den Sie im Falle dieser Ausnahme befolgen.

Wenn Sie beispielsweise den Benutzer auffordern, eine Zahl einzugeben, können Sie die Eingabe mithilfe von int() konvertieren, wodurch eine ValueError ausgelöst wird. Sie können dies leicht wiederherstellen, indem Sie einfach den Benutzer auffordern, es erneut zu versuchen. Wenn Sie also die Variable ValueError abfragen und den Benutzer erneut dazu auffordern, wäre dies ein geeigneter Plan. Ein anderes Beispiel wäre, wenn Sie eine Konfiguration aus einer Datei lesen möchten und diese Datei nicht vorhanden ist. Da es sich um eine Konfigurationsdatei handelt, verfügen Sie möglicherweise über eine Standardkonfiguration als Fallback, sodass die Datei nicht genau erforderlich ist. Es wäre also ein guter Plan, eine FileNotFoundError zu übernehmen und einfach die Standardkonfiguration anzuwenden. In beiden Fällen haben wir eine sehr spezifische Ausnahme, die wir erwarten, und wir haben einen ebenso spezifischen Plan, um sich davon zu erholen. Daher wird in jedem Fall explizit nur exceptdiese bestimmte-Ausnahme angegeben.

Wenn wir jedoch alles einfangen würden, dann besteht zusätzlich zu den Ausnahmen, von denen wir bereit sind, sich zu erholen, die Möglichkeit, dass wir Ausnahmen bekommen, die wir nicht erwartet haben und die wir tatsächlich nicht können sich erholen von; oder sollte sich nicht von erholen.

Nehmen wir das Beispiel der Konfigurationsdatei von oben. Im Falle einer fehlenden Datei haben wir nur unsere Standardkonfiguration angewendet. Möglicherweise haben Sie zu einem späteren Zeitpunkt entschieden, die Konfiguration automatisch zu speichern (die Datei ist also beim nächsten Mal vorhanden). Nun stellen wir uns vor, wir erhalten stattdessen eine IsADirectoryError oder eine PermissionError . In solchen Fällen möchten wir wahrscheinlich nicht fortfahren; Wir könnten immer noch unsere Standardkonfiguration anwenden, können die Datei jedoch später nicht speichern. Wahrscheinlich wollte der Benutzer auch eine benutzerdefinierte Konfiguration haben. Daher ist es wahrscheinlich nicht erwünscht, die Standardwerte zu verwenden. Daher möchten wir den Benutzer sofort darüber informieren und wahrscheinlich auch die Programmausführung abbrechen. Aber das wollen wir nicht irgendwo tief in einem kleinen Codeteil tun. Dies ist von Bedeutung auf Anwendungsebene und sollte daher oben behandelt werden. Lassen Sie also die Ausnahme blubbern.

Ein weiteres einfaches Beispiel wird auch im Python 2 Idioms Dokument erwähnt. Hier gibt es einen einfachen Tippfehler im Code, der dazu führt, dass er bricht. Da wir jede -Ausnahme abfangen, fangen wir auch NameErrors und SyntaxErrors . Beides sind Fehler, die uns alle beim Programmieren passieren; und beides sind Fehler, die wir beim Versenden des Codes unbedingt nicht hinzufügen möchten. Aber weil wir diese auch erwischt haben, wissen wir nicht einmal, dass sie dort vorgekommen sind, und verlieren jegliche Hilfe, um das Problem zu beheben.

Es gibt aber auch gefährlichere Ausnahmen, auf die wir unwahrscheinlich vorbereitet sind. Zum Beispiel ist SystemError normalerweise etwas, das selten vorkommt und das wir nicht wirklich planen können; Dies bedeutet, dass etwas komplizierter abläuft, was uns wahrscheinlich daran hindert, die aktuelle Aufgabe fortzusetzen.

In jedem Fall ist es sehr unwahrscheinlich, dass Sie auf alles in einem kleinen Teil des Codes vorbereitet sind. In diesem Fall sollten Sie nur die Ausnahmen erfassen, auf die Sie vorbereitet sind. Einige Leute schlagen vor, zumindest Exception zu fangen, da dies keine Dinge wie SystemExit und KeyboardInterrupt enthält, die von design dazu führen, dass Ihre Bewerbung beendet wird. Es gibt nur einen Ort, an dem ich persönlich das Abfangen von Exception oder nur any -Exception akzeptiere, und das ist in einem einzigen globalen Ausnahmebehandler auf Anwendungsebene, der den einzigen Zweck hat, eine Ausnahme zu protokollieren, auf die wir nicht vorbereitet waren. Auf diese Weise können wir immer noch so viele Informationen über unerwartete Ausnahmen aufbewahren, die wir dann verwenden können, um unseren Code so zu erweitern, dass er explizit behandelt wird (wenn wir uns davon erholen können) oder - im Falle eines Fehlers - um Testfälle zu erstellen es wird nicht wieder vorkommen Aber das funktioniert natürlich nur, wenn wir immer nur die Ausnahmen wahrnehmen, die wir bereits erwartet haben.Versuchen Sie zu vermeiden, außer Blöcke zu übergeben.

Wenn wir eine kleine Auswahl spezifischer Ausnahmen explizit erfassen, gibt es viele Situationen, in denen es uns gut geht, wenn wir einfach nichts tun. In solchen Fällen ist es einfach gut, except SomeSpecificException: pass zu haben. Meistens ist dies jedoch nicht der Fall, da wir wahrscheinlich etwas Code benötigen, der mit dem Wiederherstellungsprozess zusammenhängt (wie oben erwähnt). Dies kann zum Beispiel etwas sein, das die Aktion erneut wiederholt, oder stattdessen einen Standardwert festlegen.

Wenn dies jedoch nicht der Fall ist, zum Beispiel weil unser Code bereits so strukturiert ist, dass er wiederholt wird, bis er erfolgreich ist, ist das Passing gut genug. In unserem Beispiel von oben möchten wir den Benutzer möglicherweise zur Eingabe einer Nummer auffordern. Da wir wissen, dass Benutzer das, was wir von ihnen verlangen, nicht gerne tun, können wir es vielleicht einfach in eine Schleife schreiben, sodass es so aussehen könnte:.

def askForNumber (): while True: try: return int(input('Please enter a number: ')) except ValueError: pass

except ein Zeichen dafür, dass wir nicht wirklich auf die Ausnahme vorbereitet waren, die wir gerade bemerken. Wenn diese Ausnahmen nicht einfach sind (wie ValueError oder TypeError) und der Grund für das Passieren offensichtlich ist, versuchen Sie, das Passieren zu vermeiden. Wenn wirklich nichts zu tun ist (und Sie sich absolut sicher sind), sollten Sie einen Kommentar hinzufügen, warum dies der Fall ist. Andernfalls erweitern Sie den Except-Block, um tatsächlich Wiederherstellungscode einzuschließen.

except: pass.

Der schlimmste Täter ist jedoch die Kombination aus beiden. Dies bedeutet, dass wir bereitwillig any Fehler auffangen, obwohl wir absolut nicht darauf vorbereitet sind und wir auch nichts dagegen tun. Sie möchten den Fehler protokollieren und wahrscheinlich auch erneut starten, um die Anwendung noch zu beenden (es ist unwahrscheinlich, dass Sie nach einem MemoryError wie gewohnt fortfahren können). Durch das Passieren bleibt die Anwendung jedoch nicht nur lebendig (je nachdem, wo Sie sich natürlich einfangen), sondern es werden auch alle Informationen weggeworfen, sodass der Fehler nicht entdeckt werden kann.

.


Das Fazit lautet also: Fangen Sie nur Ausnahmen auf, von denen Sie wirklich erwarten und bereit sind, sich davon zu erholen; Alle anderen sind wahrscheinlich Fehler, die Sie beheben sollten, oder auf etwas, auf die Sie sowieso nicht vorbereitet sind. Das Übergeben von bestimmten Ausnahmen ist in Ordnung, wenn Sie wirklich nichts dagegen unternehmen müssen. In allen anderen Fällen ist dies nur ein Zeichen der Anmaßung und des Faulenzens. Und Sie wollen das definitiv reparieren.

So the bottom line is: Catch only exceptions you really expect and are prepared to recover from; all others are likely either mistakes you should fix, or something you are not prepared for anyway. Passing specific exceptions is fine if you really don’t need to do something about them. In all other cases, it’s just a sign of presumption and being lazy. And you definitely want to fix that.

292
poke

Das Hauptproblem hier ist, dass alle Fehler ignoriert werden: Nicht genügend Speicher, CPU brennt, Benutzer möchte stoppen, Programm möchte beenden, Jabberwocky tötet Benutzer.

Das ist viel zu viel. In Ihrem Kopf denken Sie "Ich möchte diesen Netzwerkfehler ignorieren". Wenn etwas unerwartet schief geht, wird Ihr Code still fortgesetzt und bricht auf völlig unvorhersehbare Weise ab, so dass niemand debuggen kann.

Deshalb sollten Sie sich darauf beschränken, nur einige Fehler zu ignorieren und den Rest durchzulassen.

257
Aaron Digulla

Die Ausführung Ihres Pseudocodes wörtlich - gibt nicht einmal einen Fehler an:

try:
    something
except:
    pass

als wäre es ein vollkommen gültiger Code, anstatt eine NameError zu werfen. Ich hoffe, das ist nicht das, was du willst.

71
YS-L

Warum ist „außer: pass“ eine schlechte Programmierpraxis?

Warum ist das so schlimm?

try:
    something
except:
    pass

Dadurch werden alle möglichen Ausnahmen erfasst, einschließlich GeneratorExit, KeyboardInterrupt und SystemExit. Hierbei handelt es sich um Ausnahmen, die Sie wahrscheinlich nicht beabsichtigen. Es ist das Gleiche wie das Fangen von BaseException.

try:
    something
except BaseException:
    pass

Ältere Versionen der Dokumentation sagen :

Da jeder Fehler in Python eine Ausnahme auslöst, kann die Verwendung von except: dazu führen, dass viele Programmierfehler wie Laufzeitprobleme aussehen, was den Debugging-Prozess behindert.

Python-Ausnahmehierarchie

Wenn Sie eine übergeordnete Ausnahmeklasse abfangen, können Sie auch alle untergeordneten Klassen abfangen. Es ist viel eleganter, nur die Ausnahmen zu erfassen, die Sie behandeln möchten.

Hier ist die Python 3 Ausnahmehierarchie - willst du sie wirklich fangen ?:

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

Tu das nicht

Wenn Sie diese Form der Ausnahmebehandlung verwenden:

try:
    something
except: # don't just do a bare except!
    pass

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

Hier ist ein weiteres Beispiel, das dasselbe unerwünschte Verhalten aufweist:

except BaseException as e: # don't do this either - same as bare!
    logging.info(e)

Versuchen Sie stattdessen, nur die bestimmte Ausnahme zu finden, nach der Sie suchen. Wenn Sie beispielsweise wissen, dass bei einer Konvertierung möglicherweise ein Wertfehler auftritt:

try:
    foo = operation_that_includes_int(foo)
except ValueError as e:
    if fatal_condition(): # You can raise the exception if it's bad,
        logging.info(e)   # but if it's fatal every time,
        raise             # you probably should just not catch it.
    else:                 # Only catch exceptions you are prepared to handle.
        foo = 0           # Here we simply assign foo to 0 and continue. 

Weitere Erklärung mit einem anderen Beispiel

Möglicherweise tun Sie dies, weil Sie im Web gescrapt wurden und eine Variable, UnicodeError, erhalten haben. Da Sie jedoch den umfangreichsten Exception-Catching verwendet haben, wird Ihr Code, der möglicherweise andere grundlegende Fehler aufweist, versuchen, zum Abschluss auszuführen und zu verschwenden Bandbreite, Verarbeitungszeit, Verschleiß an Ihrer Ausrüstung, Speicherplatzmangel, Sammeln von Mülldaten usw. 

Wenn andere Personen Sie auffordern, den Vorgang abzuschließen, damit sie sich auf Ihren Code verlassen können, verstehe ich das Gefühl, alles erledigt zu haben. Wenn Sie jedoch bereit sind, bei der Entwicklung geräuschlos zu scheitern, haben Sie die Möglichkeit, Probleme zu beheben, die möglicherweise nur zeitweise auftauchen. Dies wäre jedoch langfristig ein kostspieliger Fehler. 

Durch eine genauere Fehlerbehandlung kann Ihr Code robuster sein.

45
Aaron Hall
>>> import this

Das Zen von Python, von Tim Peters

Schön ist besser als hässlich.
Explicit ist besser als implizit.
Einfach ist besser als komplex.
Komplex ist besser als kompliziert.
Flat ist besser als verschachtelt.
Sparse ist besser als dicht.
Lesbarkeit zählt.
Sonderfälle sind nicht speziell genug, um die Regeln zu brechen.
Obwohl Praktikabilität die Reinheit übertrifft.
Fehler sollten niemals lautlos vergehen.
Sofern nicht ausdrücklich zum Schweigen gebracht.
In Anbetracht der Mehrdeutigkeit lehnen Sie die Versuchung ab, zu raten.
Es sollte einen - und vorzugsweise nur einen - offensichtlichen Weg geben, dies zu tun.
Obwohl dies auf den ersten Blick nicht offensichtlich ist, es sei denn, Sie sind Niederländer.
Jetzt ist besser als nie.
Obwohl nie besser als right ist.
Wenn die Implementierung schwer zu erklären ist, ist das keine gute Idee.
Wenn die Implementierung leicht zu erklären ist, kann dies eine gute Idee sein.
Namensräume sind eine hupende großartige Idee - machen wir mehr davon!

Also hier ist meine Meinung. Wenn Sie einen Fehler finden, sollten Sie etwas tun, um ihn zu behandeln, d. H. Schreiben Sie ihn in eine Logdatei oder in etwas anderes. Zumindest informiert es Sie, dass früher ein Fehler aufgetreten ist.

26
Booster

Sie sollten mindestens except Exception: verwenden, um Systemausnahmen wie SystemExit oder KeyboardInterrupt abzufangen. Hier ist link to docs.

Im Allgemeinen sollten Sie explizite Ausnahmen definieren, die Sie abfangen möchten, um unerwünschte Ausnahmen zu vermeiden. Sie sollten wissen, welche Ausnahmen Sie ignorieren.

23
Tupteq

Erstens verletzt es zwei Prinzipien von Zen of Python :

  • Explicit ist besser als implizit
  • Fehler sollten niemals unbemerkt vergehen

Was es bedeutet, ist, dass Sie Ihren Fehler absichtlich unbemerkt durchlaufen lassen. Außerdem wissen Sie nicht, welcher Fehler genau aufgetreten ist, da except: pass alle Ausnahmen abfängt. 

Zweitens: Wenn wir versuchen, uns vom Zen von Python zu abstrahieren und in Bezug auf die Vernunft zu sprechen, sollten Sie wissen, dass Sie mit except:passkein Wissen und keine Kontrolle in Ihrem System haben. Als Faustregel gilt, eine Ausnahme auszulösen, wenn ein Fehler auftritt, und entsprechende Maßnahmen zu ergreifen. Wenn Sie nicht im Voraus wissen, welche Aktionen dies sein sollten, protokollieren Sie den Fehler mindestens (und führen Sie die Ausnahme erneut aus):

try:
    something
except:
    logger.exception('Something happened')

Normalerweise jedoch wenn Sie versuchen, eine Ausnahme zu erkennen, machen Sie wahrscheinlich etwas falsch! 

12

Der Grund Nr. 1 wurde bereits angegeben - er verbirgt Fehler, die Sie nicht erwartet hatten. 

(# 2) - Es macht Ihren Code für andere schwer zu lesen und zu verstehen. Wenn Sie eine FileNotFoundException abfangen, wenn Sie versuchen, eine Datei zu lesen, ist es für einen anderen Entwickler offensichtlich, welche Funktionalität der "catch" -Block haben sollte. Wenn Sie keine Ausnahme angeben, benötigen Sie zusätzliche Kommentare, um zu erläutern, was der Block tun soll.

(# 3) - Es zeigt faules Programmieren. Wenn Sie das generische try/catch verwenden, bedeutet dies, dass Sie entweder die möglichen Laufzeitfehler in Ihrem Programm nicht verstehen oder nicht wissen, welche Ausnahmen in Python möglich sind. Das Erfassen eines bestimmten Fehlers zeigt, dass Sie sowohl Ihr Programm als auch den Fehlerbereich verstehen, den Python auslöst. Dies führt dazu, dass andere Entwickler und Code-Reviewer Ihrer Arbeit vertrauen.

11
Kevin

Welche Ausgabe produziert dieser Code?

fruits = [ 'Apple', 'pear', 'carrot', 'banana' ]

found = False
try:
     for i in range(len(fruit)):
         if fruits[i] == 'Apple':
             found = true
except:
     pass

if found:
    print "Found an Apple"
else:
    print "No apples in list"

Stellen Sie sich nun vor, der try-except-Block besteht aus Hunderten von Zeilen für Aufrufe einer komplexen Objekthierarchie und wird selbst in der Mitte des Aufrufbaums eines großen Programms aufgerufen. Wenn das Programm schief geht, wo fangen Sie an zu suchen?

11
Ian Harvey

Das except:pass-Konstrukt bringt im Wesentlichen alle Ausnahmebedingungen zum Schweigen, während der Code im try:-Block ausgeführt wird.

Was diese schlechte Praxis ausmacht ist, dass es normalerweise nicht das ist, was Sie wirklich wollen. Häufig tritt eine bestimmte Bedingung auf, die Sie zum Schweigen bringen möchten, und except:pass ist ein zu stumpfes Instrument. Es wird die Arbeit erledigen, aber es werden auch andere Fehlerbedingungen verdeckt, die Sie wahrscheinlich nicht erwartet haben, aber Sie möchten vielleicht auf andere Weise damit umgehen.

Was dies in Python besonders wichtig macht, ist, dass Ausnahmen nicht notwendigerweise Fehler sind durch die Redewendungen dieser Sprache. Sie werden natürlich oft so verwendet, wie in den meisten Sprachen. Vor allem Python hat sie jedoch gelegentlich verwendet, um einen alternativen Exit-Pfad aus einigen Code-Tasks zu implementieren, der nicht wirklich zum normalen laufenden Fall gehört, aber immer noch bekannt ist und gelegentlich bekannt wird. SystemExit wurde bereits als altes Beispiel erwähnt, aber das gängigste Beispiel ist heute StopIteration. Die Verwendung von Ausnahmen auf diese Weise löste viele Kontroversen aus, vor allem, wenn Iteratoren und Generatoren erstmals in Python eingeführt wurden, aber schließlich die Idee siegte.

11
The Spooniest

Im Allgemeinen können Sie einen Fehler/eine Ausnahme in einer der Kategorien drei Kategorien klassifizieren:

  • Fatal: Nicht deine Schuld, du kannst sie nicht verhindern, du kannst sie nicht wiederherstellen. Sie sollten sie auf keinen Fall ignorieren und fortfahren und Ihr Programm in einem unbekannten Zustand belassen. Lassen Sie den Fehler einfach Ihr Programm beenden, es gibt nichts, was Sie tun können.

  • Boneheaded: Ihre eigene Schuld, höchstwahrscheinlich aufgrund eines Versehens, eines Fehlers oder eines Programmierfehlers. Sie sollten den Fehler beheben. Wieder sollten Sie ganz sicher nicht ignorieren und fortfahren.

  • Exogenous: Sie können diese Fehler in Ausnahmesituationen erwarten, z. B. Datei nicht gefunden oder Verbindung beendet. Sie sollten diese Fehler explizit behandeln, und nur diese.

In allen Fällen wird except: pass Ihr Programm nur in einem unbekannten Zustand verlassen, in dem es zu mehr Schaden kommen kann.

10

Meiner Meinung nach haben Fehler einen Grund, dass mein Ton dumm ist, aber so ist es. Eine gute Programmierung führt nur dann zu Fehlern, wenn Sie damit umgehen müssen. Wie ich vor einiger Zeit gelesen habe, ist "die Pass-Anweisung eine Anweisung, die zeigt, dass der Code später eingefügt wird". Wenn Sie also eine leere Ausnahme-Anweisung haben möchten, können Sie dies gerne tun, aber für ein gutes Programm ist dies der Fall ein Teil fehlt weil Sie nicht mit den Dingen umgehen, die Sie haben sollten. Wenn Sie Ausnahmen sehen, haben Sie die Möglichkeit, Eingabedaten zu korrigieren oder Ihre Datenstruktur zu ändern, damit diese Ausnahmen nicht mehr auftreten (in den meisten Fällen (Netzwerkausnahmen, Allgemeine Eingabeausnahmen) zeigen Ausnahmen jedoch an, dass die nächsten Programmteile nicht ordnungsgemäß ausgeführt werden. Beispielsweise kann eine NetworkException auf eine unterbrochene Netzwerkverbindung hinweisen und das Programm kann in den nächsten Programmschritten keine Daten senden/empfangen.

Die Verwendung eines Passblocks für nur einen Ausführungsblock ist jedoch gültig, da Sie immer noch zwischen den Ausnahmetypen unterscheiden. Wenn Sie also alle Ausnahmeblöcke in einen einzigen einfügen, ist er nicht leer:

try:
    #code here
except Error1:
    #exception handle1

except Error2:
    #exception handle2
#and so on

kann auf diese Weise neu geschrieben werden:

try:
    #code here
except BaseException as e:
    if isinstance(e, Error1):
        #exception handle1

    Elif isinstance(e, Error2):
        #exception handle2

    ...

    else:
        raise

So können auch mehrere Except-Blöcke mit Pass-Anweisungen zu Code führen, dessen Struktur spezielle Ausnahmetypen behandelt.

5
Sirac

Einfach ausgedrückt: Wenn eine Ausnahme oder ein Fehler ausgelöst wird, stimmt etwas nicht. Es ist zwar nicht etwas ganz Falsches, aber das Erstellen, Werfen und Erfassen von Fehlern und Ausnahmen, nur um goto-Anweisungen zu verwenden, ist keine gute Idee und wird selten gemacht. In 99% der Fälle gab es irgendwo ein Problem.

Probleme müssen gelöst werden. So wie es im Leben ist, beim Programmieren: Wenn Sie Probleme einfach in Ruhe lassen und versuchen, sie zu ignorieren, gehen sie oft nicht einfach alleine weg. Stattdessen werden sie größer und vermehren sich. Um zu verhindern, dass ein Problem an Ihnen wächst und weiter unten auf der Straße schlägt, müssen Sie entweder 1) das Problem beseitigen und anschließend das Chaos aufräumen oder 2) es eindämmen und anschließend das Chaos beseitigen.

Nur Ausnahmen und Fehler zu ignorieren und sie so zu lassen, ist ein guter Weg, um Speicherverluste, hervorragende Datenbankverbindungen, unnötige Sperren von Dateiberechtigungen zu erfahren.

In seltenen Fällen ist das Problem so winzig, trivial und - abgesehen davon, dass Sie einen Versuch brauchen ... catch block - in sich geschlossen , dass es wirklich keine Unordnung gibt, die danach wieder aufgeräumt werden muss. Dies sind die einzigen Gelegenheiten, bei denen diese bewährte Methode nicht unbedingt zutrifft. Nach meiner Erfahrung hat dies im Allgemeinen dazu geführt, dass das, was der Code tut, im Grunde unbedeutend und verzichtbar ist, und etwas wie Wiederholungsversuche oder spezielle Nachrichten sind weder die Komplexität wert, noch belasten sie den Thread.

In meiner Firma lautet die Regel, etwas fast immer in einem catch-Block auszuführen, und wenn Sie nichts tun, müssen Sie immer einen Kommentar mit einem sehr guten Grund angeben, warum dies nicht der Fall ist. Sie dürfen niemals einen leeren Sperrblock passieren oder verlassen, wenn etwas zu tun ist.

5
Panzercrisis

Alle bisher angesprochenen Kommentare sind gültig. Wo möglich, müssen Sie angeben, welche Ausnahme Sie genau ignorieren möchten. Wo immer möglich, müssen Sie die Ursache der Ausnahme analysieren und nur das ignorieren, was Sie ignorieren wollten, und nicht den Rest. Wenn eine Anwendung zu einem "spektakulären Absturz" der Anwendung führt, dann ist es wahrscheinlich so, denn es ist viel wichtiger, das Unerwartete zu erfahren, als es passiert ist, als zu verbergen, dass das Problem jemals aufgetreten ist.

Trotz alledem sollten Sie keine Programmierpraxis als vorrangig betrachten. Das ist blöd. Es gibt immer die Zeit und den Ort, um einen Ausnahmeblock zu ignorieren.

Ein anderes Beispiel für idiotische Obergrenzen ist die Verwendung des Operators goto. Als ich in der Schule war, hat uns unser Professor goto Operator beigebracht, um nur zu erwähnen, dass Sie ihn NICHT benutzen werden. Glauben Sie nicht, dass die Leute Ihnen sagen, dass xyz niemals verwendet werden sollte und dass es kein Szenario geben kann, in dem es nützlich ist. Es gibt immer etwas.

4
galets

Die Fehlerbehandlung ist bei der Programmierung sehr wichtig. Sie müssen dem Benutzer zeigen, was schiefgegangen ist. In sehr wenigen Fällen können Sie die Fehler ignorieren. Dies ist eine sehr schlechte Programmierpraxis.

2
fastcodejava

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

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

Beachten Sie, dass im angegebenen Beispiel der Programmstatus gleich bleibt, unabhängig davon, ob die Ausnahme auftritt oder nicht. Das heißt, somefile.tmp wird immer nicht vorhanden.

0
Mateen Ulhaq