Das Hauptargument des Buches ist, dass die Ausnahmeversion des Codes besser ist, da sie alles auffängt, was Sie möglicherweise übersehen hätten, wenn Sie versucht hätten, Ihre eigene Fehlerprüfung zu schreiben.
Ich denke, diese Aussage trifft nur unter ganz bestimmten Umständen zu - wobei es Ihnen egal ist, ob die Ausgabe korrekt ist.
Es besteht kein Zweifel, dass das Auslösen von Ausnahmen eine solide und sichere Praxis ist. Sie sollten dies tun, wenn Sie das Gefühl haben, dass sich im aktuellen Status des Programms etwas befindet, mit dem Sie (als Entwickler) nicht umgehen können oder wollen.
In Ihrem Beispiel geht es jedoch darum , Ausnahmen einzufangen . Wenn Sie eine Ausnahme feststellen , schützen Sie sich nicht vor Szenarien, die Sie möglicherweise übersehen haben. Sie tun genau das Gegenteil: Sie gehen davon aus, dass Sie kein Szenario übersehen haben, das diese Art von Ausnahme verursacht haben könnte, und sind daher zuversichtlich, dass es in Ordnung ist, sie abzufangen (und somit zu verhindern, dass das Programm beendet wird, wie es jede unaufgefangene Ausnahme tun würde).
Wenn Sie den ValueError
Ausnahmeansatz verwenden und eine Ausnahme sehen, überspringen Sie eine Zeile. Bei Verwendung des herkömmlichen Ansatzes ohne Ausnahmen wird die Anzahl der zurückgegebenen Werte von gezählt split
, und bei weniger als 2 wird eine Zeile übersprungen. Sollten Sie sich mit dem Ausnahmeansatz sicherer fühlen, da Sie möglicherweise einige andere "Fehler" -Situationen bei Ihrer herkömmlichen Fehlerprüfung vergessen haben und except ValueError
diese für Sie abfangen würden?
Dies hängt von der Art Ihres Programms ab.
Wenn Sie beispielsweise einen Webbrowser oder einen Videoplayer schreiben, sollte ein Problem mit Eingaben nicht dazu führen, dass er mit einer nicht erfassten Ausnahme abstürzt. Es ist weitaus besser, etwas aus der Ferne Vernünftiges (auch wenn es streng genommen falsch ist) auszugeben, als zu beenden.
Wenn Sie eine Anwendung schreiben, bei der es auf Korrektheit ankommt (z. B. Geschäfts- oder Entwicklungssoftware), ist dies ein schrecklicher Ansatz. Wenn Sie ein ausgelöstes Szenario vergessen ValueError
haben, können Sie dieses unbekannte Szenario im Stillen ignorieren und einfach die Zeile überspringen. So entstehen sehr subtile und kostspielige Fehler in der Software.
Sie könnten denken, dass die einzige Möglichkeit, die Sie ValueError
in diesem Code sehen können, darin besteht, split
nur einen Wert (anstelle von zwei) zurückzugeben. Aber was ist, wenn Ihre print
Anweisung später einen Ausdruck verwendet, der ValueError
unter bestimmten Bedingungen ausgelöst wird? Dies führt dazu, dass Sie einige Zeilen überspringen, nicht weil sie fehlen :
, sondern weil sie print
nicht funktionieren. Dies ist ein Beispiel für einen subtilen Fehler, auf den ich mich früher bezogen habe - Sie würden nichts bemerken, sondern nur einige Zeilen verlieren.
Ich empfehle, keine Ausnahmen im Code abzufangen (aber nicht zu erhöhen!), Bei denen das Erzeugen einer falschen Ausgabe schlechter ist als das Beenden. Das einzige Mal, dass ich eine Ausnahme in einem solchen Code abfange, ist, wenn ich einen wirklich trivialen Ausdruck habe, sodass ich leicht überlegen kann, was die einzelnen möglichen Ausnahmetypen verursachen kann.
Die Auswirkungen der Verwendung von Ausnahmen auf die Leistung sind (in Python) trivial, es sei denn, Ausnahmen treten häufig auf.
Wenn Sie Ausnahmen verwenden, um routinemäßig auftretende Bedingungen zu behandeln, können Sie in einigen Fällen enorme Leistungskosten zahlen. Angenommen, Sie führen einen Befehl aus der Ferne aus. Sie können überprüfen, ob Ihr Befehlstext mindestens die Mindestvalidierung (z. B. Syntax) besteht. Oder Sie können warten, bis eine Ausnahme ausgelöst wird (was erst geschieht, nachdem der Remoteserver Ihren Befehl analysiert und ein Problem damit gefunden hat). Ersteres ist offensichtlich um Größenordnungen schneller. Ein weiteres einfaches Beispiel: Sie können überprüfen, ob eine Zahl null bis zehn Mal schneller ist als der Versuch, die Division auszuführen, und dann die ZeroDivisionError-Ausnahme abfangen.
Diese Überlegungen spielen nur eine Rolle, wenn Sie häufig fehlerhafte Befehlszeichenfolgen an Remoteserver senden oder Argumente mit dem Wert Null empfangen, die Sie für die Aufteilung verwenden.
Hinweis: Ich gehe davon aus, dass Sie except ValueError
anstelle des Gerechten verwenden würden except
. Wie andere betonten, und wie das Buch selbst auf einigen Seiten sagt, sollten Sie niemals nackte verwenden except
.
Ein weiterer Hinweis: Der richtige Ansatz ohne Ausnahmen besteht darin, die Anzahl der von zurückgegebenen Werte zu zählen split
, anstatt zu suchen :
. Letzteres ist viel zu langsam, da es die von Ihnen geleistete Arbeit wiederholt split
und die Ausführungszeit möglicherweise fast verdoppelt.