Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Python

Wie man Ausnahmen in Python nicht behandelt

Ich sehe viele Leute, die mit Ausnahmen falsch umgehen. Vielleicht trifft dies auch auf Sie zu. Kommt Ihnen die folgende Situation bekannt vor?

Sie schreiben Code, wissen aber, dass die von Ihnen verwendete Bibliothek möglicherweise eine Ausnahme auslöst. Sie erinnern sich nicht genau, welche. An diesem Punkt ist es verlockend, sogenannte Catch-All-Blöcke zu verwenden und mit den lustigen Sachen weiterzumachen.

Inhaltsverzeichnis

Der schlechteste Weg, es zu tun

Das Schlimmste, was Sie tun können, ist, einen try-außer-Block zu erstellen, der alles abfängt. Mit Catch-all meine ich so etwas wie:

try:
    ...
except:
    pass

Catch-All-Blöcke wie diese sind schlecht, weil:

  1. Sie haben keine Ahnung, welche anderen Ausnahmen ausgelöst werden könnten (dazu später mehr).
  2. Wir verstecken die Ausnahme, indem wir stillschweigend pass verwenden, anstatt den Fehler zu protokollieren.

Außerdem fängt eine leere Ausnahme alles ab, einschließlich KeyboardInterrupt (Strg + c), SystemExit , und sogar NameErrors ! Das bedeutet, dass folgender Code nicht sauber gestoppt werden kann:

from time import sleep

while True:
    try:
        print("Try and stop me")
        sleep(1)
    except:
        print("Don't.. stop.. me now!")

Fühlen Sie sich frei, es zu versuchen. Sie müssen Ihr Terminalfenster schließen oder den Python-Prozess beenden, um dieses Programm zu stoppen.

Ein etwas besserer Weg, um alle Ausnahmen abzufangen

Im Gegensatz dazu bei Verwendung von except Exception , obwohl es immer noch eine schnelle und schmutzige Möglichkeit ist, zu viele Ausnahmen abzufangen, können Sie zumindest den laufenden Prozess ordnungsgemäß stoppen:

from time import sleep
while True:
    try:
        print("Try and stop me")
        sleep(1)
    except Exception:
        print("Ok I'll stop!")

Beim Fangen von Exception Sie werden SystemExit nicht fangen , KeyboardInterrupt und andere solche Ausnahmen. Warum, fragst du?

Alle Ausnahmen erben von einer Klasse namens BaseException . Laut offizieller Dokumentation:„In a try Anweisung mit einem except Klausel, die eine bestimmte Klasse erwähnt, behandelt diese Klausel auch alle Ausnahmeklassen, die von dieser Klasse abgeleitet sind.“ Ein leerer except entspricht except BaseException , daher werden alle möglichen Ausnahmen abgefangen.

Im Gegensatz dazu die Klasse Exception ist definiert als:„Alle eingebauten, nicht systembeendenden Ausnahmen werden von dieser Klasse abgeleitet. Alle benutzerdefinierten Ausnahmen sollten ebenfalls von dieser Klasse abgeleitet werden.“

Es kommt noch schlimmer

Im folgenden Beispiel verwenden wir die os-Bibliothek, um das aktuelle Arbeitsverzeichnis abzurufen. Allerdings haben sich meine fetten kleinen Finger vertippt:

import os
try:
    working_dir = os.getcdw()
    print(working_dir)
except:
    print('error')

Weil os.getcdw keine Funktion im os-Modul ist, wird ein NameError ausgelöst. Anstatt fehlzuschlagen, fängt die Exception-Klausel den Fehler ab, gibt „error“ aus und das Programm wird trotz unseres eklatanten Tippfehlers fortgesetzt. Leider ist dieser nicht durch Fangen von Exception lösbar entweder!

Anscheinend ist unser kleiner Trick aus Schritt eins keine Lösung für alle unsere Probleme. Also, was sollte wir tun?

Fang, was du bewältigen kannst

Ein Satz, der oft über Ausnahmen gehört wird, lautet:Fangen Sie, was Sie handhaben können . Viele Entwickler sind versucht, sich direkt mit Ausnahmen zu befassen, obwohl es oft besser ist, die Ausnahme an einen Teil Ihres Programms weiterzugeben, der sie tatsächlich verarbeiten kann.

Betrachten wir zum Beispiel den Teil eines Texteditors, der Dateien öffnet und lädt, nennen wir ihn den OpenFile Klasse. Wenn der Benutzer angefordert hat, eine Datei zu öffnen, die nicht vorhanden ist, können Sie diesen Fehler entweder direkt behandeln oder ihn weitergeben lassen.

In diesem Fall ist es besser, die Ausnahme an den Aufrufer weiterzugeben, da OpenFile hat keine ahnung wie schlimm diese ausnahme für den anrufer ist. Der Anrufer kann die Situation auf mehrere Arten handhaben:

So oder so, es ist nicht die OpenFile Klasse, um zu entscheiden, was im Falle eines FileNotFoundError zu tun ist .

Soll also eine Ausnahme immer propagiert werden? Nein. Eine mögliche Ausnahme, die in der FileOpen-Klasse behandelt werden kann, ist TimeoutError . Vielleicht möchten Sie es zum Beispiel ein paar Mal wiederholen, ohne den Anrufer mit dem Fehler zu belästigen. Dies ist eine Ausnahme von OpenFile verarbeiten kann, also ist es in Ordnung, es abzufangen und es erneut zu versuchen.

Schlussfolgerung

Sie sollten unter keinen Umständen mehr Ausnahmen abfangen, als Sie bewältigen können. Blanket-Außer-Blöcke sind ein Rezept für Fehler und unvorhersehbaren Code. Mit anderen Worten:Fangen Sie, was Sie vertragen können.

Wenn Sie Ihren Code mit der Matra „Fangen Sie, was Sie handhaben können“ schreiben, bricht das Schreiben von Catch-All-Blöcken alle Regeln. Also bitte hör auf damit. Als Übung könnten Sie einen Teil Ihres vorhandenen Codes noch einmal durchgehen und sehen, ob er mit diesem neuen Wissen verbessert werden kann!


Python

  1. Python-Operatoren
  2. Python-Fehler und eingebaute Ausnahmen
  3. Benutzerdefinierte Python-Ausnahmen
  4. Wie bekomme ich das aktuelle Datum und die Uhrzeit in Python?
  5. Java fängt mehrere Ausnahmen ab
  6. Wie man beim Lehren neuer Software nicht scheitert
  7. Python Print()-Anweisung:Drucken mit Beispielen
  8. Python Dictionary Append:So fügen Sie ein Schlüssel/Wert-Paar hinzu
  9. Python New Line:So drucken Sie OHNE Newline in Python
  10. Python-Durchschnitt:So finden Sie den DURCHSCHNITT einer Liste in Python