Wenn etwas schiefgeht
Wenn Python nicht tun kann, was Sie verlangen, löst es eine Ausnahme aus: float("abc") löst ValueError aus, {}["x"] KeyError, 1 / 0 ZeroDivisionError, und das Öffnen einer fehlenden Datei FileNotFoundError. Behandelt sie nichts, stoppt das Programm und gibt einen Traceback aus, die Kette von Aufrufen, die dorthin führte, von unten nach oben zu lesen. Das ist das richtige Ergebnis für einen echten Fehler. Für vorhersehbare Probleme, etwa einen falschen Preis, den ein Nutzer eingibt, behandeln Sie die Ausnahme mit try und except.
# Handle an expected problem
def to_price(text):
try:
return float(text)
except ValueError:
return None
print(to_price("184.25")) # 184.25
print(to_price("abc")) # None
# An unhandled one stops the program with a traceback
# print(int("abc")) # ValueError: invalid literal for int()...Nur fangen, was Sie erwarten
Nennen Sie den Ausnahmetyp: except ValueError:. Ein nacktes except: oder except Exception: verschluckt auch Fehler, die Sie nie verstecken wollten, etwa einen TypeError durch Übergabe von None, und das Programm läuft mit falschen Daten weiter. Mehrere Typen können sich einen Handler teilen, except (ValueError, KeyError):, oder eigene haben. Python probiert die Handler der Reihe nach und führt den ersten passenden aus. Mit except ValueError as error: behalten Sie den Fehler und können ihn untersuchen.
# Specific handlers, tried in order
def read_quantity(text):
try:
return int(text)
except ValueError as error:
print("not a whole number:", error)
return 0
except TypeError:
print("expected text, got something else")
return 0
print(read_quantity("200")) # 200
print(read_quantity("2.5")) # prints the message, then 0
print(read_quantity(None)) # prints the message, then 0else und finally
Zwei optionale Teile vervollständigen die Anweisung. else: läuft nur, wenn der try-Block nichts ausgelöst hat; so bleibt die riskante Zeile kurz und der Folgecode außerhalb des Schutzes. finally: läuft immer, mit oder ohne Fehler, auch nach einem return: nutzen Sie es zum Aufräumen. Oft erledigt schon ein with-Block das Aufräumen für Sie, etwa bei Dateien.
# else runs on success, finally runs always
def describe(text):
try:
price = float(text)
except ValueError:
print("bad price")
else:
print("price is", price)
finally:
print("done with", repr(text))
describe("184.25")
# price is 184.25
# done with '184.25'
describe("abc")
# bad price
# done with 'abc'Eigene Fehler auslösen
Eine Funktion, die einen unzulässigen Wert erhält, sollte laut ablehnen mit raise, statt stillschweigend etwas Falsches zurückzugeben: raise ValueError("price must be positive"). Wählen Sie den passenden eingebauten Typ (ValueError für richtigen Typ, aber schlechten Wert, TypeError für falschen Typ) und schreiben Sie eine Meldung, die sagt, was falsch war. Der Aufrufer entscheidet dann, ob er sie abfängt. In einem except-Block löst ein nacktes raise den eben gefangenen Fehler erneut aus, praktisch, wenn Sie ihn nur protokollieren wollten.
# Refuse bad input, let the caller decide
def parse_price(text):
price = float(text) # may raise ValueError itself
if not price > 0:
raise ValueError("price must be positive")
return price
for text in ["184.25", "-5", "abc"]:
try:
print(parse_price(text))
except ValueError as error:
print("rejected:", error)
# 184.25
# rejected: price must be positive
# rejected: could not convert string to float: 'abc'except, das nichts tut (except: pass), macht aus einem Absturz, den Sie hätten debuggen können, stillschweigend falsche Zahlen, was im Handelscode viel schlimmer ist. Fangen Sie einen Fehler nur dort, wo Sie eine sinnvolle Reaktion kennen: Standardwert nehmen, Element überspringen, erneut versuchen oder melden und anhalten. Sonst lassen Sie ihn zu einer Stelle aufsteigen, die weiß, was zu tun ist.try/except SpecificError: behandeln Sie die erwarteten Probleme, nicht mehr.elseläuft, wenn nichts ausgelöst wurde;finallyläuft immer.raise ValueError("message")lehnt fehlerhafte Eingaben deutlich ab.
Als Nächstes: Module und Importe, wie Sie Code aus der Standardbibliothek und aus eigenen Dateien wiederverwenden.
Lab: Was bewertet wird
- Mit
safe_floatText ohne Absturz umwandeln25 Pkt. - Mit
parse_priceeinen schlechten Preis ablehnen25 Pkt. - Mit
first_valid_pricefehlerhafte Einträge überspringen25 Pkt. - Mit
read_quantityeine fehlende oder beschädigte Datei behandeln25 Pkt.