Argumente für oder gegen die Verwendung von Try / Catch als logische Operatoren [closed]

36

Ich habe gerade einen schönen Code in unserer Unternehmens-App entdeckt, der Try-Catch-Blöcke als logische Operatoren verwendet.
Das heißt, "mache etwas Code, wenn das diesen Fehler auslöst, mache diesen Code, aber wenn das diesen Fehler auslöst, mache stattdessen diese dritte Sache".
Es verwendet "finally" als "else" -Anweisung.
Ich weiß, dass dies von Natur aus falsch ist, aber bevor ich mich für einen Kampf entschied, hoffte ich auf einige gut durchdachte Argumente.
Und hey, wenn Sie Argumente für die Verwendung von Try-Catch auf diese Weise haben, sagen Sie es bitte.

Für alle, die sich fragen, ist die Sprache C # und der fragliche Code besteht aus mehr als 30 Zeilen und sucht nach bestimmten Ausnahmen. Es werden nicht ALLE Ausnahmen behandelt.

James P. Wright
quelle
13
Ich habe nur Argumente gegen diese Praxis, und da Sie bereits überzeugt zu sein scheinen, dass es eine schlechte Idee ist, werde ich mich nicht darum kümmern, sie zu posten.
FrustratedWithFormsDesigner
15
@FrustratedWIthFormsDesigner: Das ist eine schlechte Argumentation. Was ist mit den Leuten, die nicht überzeugt sind? Was ist mit meiner eigentlichen Frage, bei der ich speziell nach Gründen frage, da ich nicht wirklich sagen kann, warum, nur dass ich weiß, dass es falsch ist?
James P. Wright
3
Meine Meinung hängt stark davon ab, was der betreffende Code tatsächlich tut. Es gibt Dinge, die nicht im Voraus überprüft werden können (oder die Rennbedingungen zulassen, wenn versucht wird, wie z. B. viele Dateioperationen - in der Verzögerung zwischen der Überprüfung und der Operation kann mit der Datei alles passieren) und die überprüft werden müssen try. Nicht jeder Ausnahmefall, der eine Ausnahme im Allgemeinen rechtfertigt, muss in diesem speziellen Fall tödlich sein. Könnten Sie es also einfacher, gleichermaßen oder robuster machen, ohne Ausnahmen zu verwenden?
11
Ich hoffe, dass sie den "finally" -Block nicht wirklich als "else" verwenden, da der "finally" -Block immer nach dem vorhergehenden Code ausgeführt wird, unabhängig davon, welche Ausnahmen ausgelöst werden.
12.
2
Welche Sprache benutzen sie? Es ist beispielsweise in OCaml völlig in Ordnung, wo die Standardbibliothek routinemäßig Ausnahmen auslöst. Die Ausnahmebehandlung ist dort sehr günstig. In CLI oder JVM wird dies jedoch nicht so effizient sein.
SK-logic,

Antworten:

50

Die Ausnahmebehandlung ist in der Regel eine teure Methode zur Flusskontrolle (sicherlich für C # und Java).

Die Laufzeitumgebung erledigt eine Menge Arbeit, wenn ein Ausnahmeobjekt erstellt wird - Zusammenstellen des Stack-Trace, Herausfinden, wo die Ausnahme behandelt wird und vieles mehr.

All dies kostet Arbeitsspeicher und CPU-Ressourcen, die nicht erweitert werden müssen, wenn Flusssteuerungsanweisungen zur Flusssteuerung verwendet werden.

Zusätzlich gibt es eine semantische Frage. Ausnahmen gelten für Ausnahmesituationen, nicht für die normale Flusskontrolle. Man sollte die Ausnahmebehandlung verwenden, um unvorhergesehene / außergewöhnliche Situationen zu behandeln, nicht wie im normalen Programmablauf, da sonst eine nicht erfasste Ausnahme viel weniger aussagt.

Abgesehen von diesen beiden geht es darum, dass andere den Code lesen. Die meisten Programmierer erwarten nicht, Ausnahmen auf diese Weise zu verwenden. Daher leidet die Lesbarkeit und das Verständnis Ihres Codes darunter. Wenn man "Exception" sieht, denkt man - etwas Schlimmes ist passiert, etwas, das normalerweise nicht passieren soll. Die Verwendung von Ausnahmen auf diese Weise ist also einfach verwirrend.

Oded
quelle
1
Ein guter Punkt zur Leistung, der jedoch auch von den Besonderheiten der Plattform abhängt.
FrustratedWithFormsDesigner
4
Wenn das der einzige Nachteil ist, danke - ich werde jeden Tag auf die Leistung verzichten, wenn ich besseren Code erhalte (außer auf leistungskritischen Pfaden), aber zum Glück macht das nur 20% des gesamten Codes aus, selbst in Anwendungen, die im Allgemeinen eine hohe Leistung aufweisen -kritisch).
5
@delnan - Nein, nicht der einzige Nachteil.
Oded
2
Mit Ausnahme des Wortes unvorhergesehen stimme ich Ihrem Beitrag zu. Es gibt Zeiten in Ihrem Code, in denen Ausnahmen auftreten. Die meisten davon sollten vorhersehbar sein, z. B. Verbindungsfehler mit der Datenbank oder einem Serviceabruf oder immer dann, wenn Sie mit nicht verwaltetem Code arbeiten. Sie erkennen Probleme, die außerhalb Ihrer Kontrolle liegen, und lösen sie. Aber ich bin damit einverstanden, dass Sie niemals eine Flusskontrolle basierend auf Ausnahmen haben sollten, die Sie in Ihrem Code vermeiden können.
SoylentGray
4
"Die Ausnahmebehandlung ist in der Regel eine teure Methode zur Steuerung des Datenflusses." Falsch für Python.
S.Lott,
17

Ich habe gerade einen schönen Code in unserer Unternehmens-App entdeckt, der Try-Catch-Blöcke als logische Operatoren verwendet. Das heißt, "mache etwas Code, wenn das diesen Fehler auslöst, mache diesen Code, aber wenn das diesen Fehler auslöst, mache stattdessen diese dritte Sache". Es verwendet "finally" als "else" -Anweisung. Ich weiß, dass das von Natur aus falsch ist ...

Wie kannst du das Wissen? Ich habe all dieses "Wissen" aufgegeben und glaube jetzt nur, dass der einfachste Code der beste ist. Angenommen, Sie möchten eine Zeichenfolge in eine optionale konvertieren, die leer ist, wenn die Analyse fehlschlägt. Es ist nichts falsch mit:

try { 
    return Optional.of(Long.valueOf(s)); 
} catch (NumberFormatException) { 
    return Optional.empty(); 
}

Ich stimme der üblichen Auslegung von "Ausnahmen gelten für außergewöhnliche Umstände" überhaupt nicht zu. Wenn eine Funktion keinen verwendbaren Wert zurückgeben kann oder eine Methode ihre Post-Bedingungen nicht erfüllen kann, lösen Sie eine Ausnahme aus. Es spielt keine Rolle, wie oft diese Ausnahmen ausgelöst werden, bis ein nachgewiesenes Leistungsproblem vorliegt.

Ausnahmen vereinfachen den Code, indem sie die Trennung der Fehlerbehandlung vom normalen Ablauf ermöglichen. Schreiben Sie einfach den einfachsten Code, und wenn es einfacher ist, try-catch zu verwenden oder eine Ausnahme auszulösen, dann tun Sie dies.

Ausnahmen vereinfachen das Testen, indem die Anzahl der Pfade durch den Code verringert wird. Eine Funktion ohne Verzweigungen führt entweder zum Abschluss oder löst eine Ausnahme aus. Eine Funktion mit mehreren ifAnweisungen zum Überprüfen auf Fehlercodes verfügt über viele mögliche Pfade. Es ist sehr einfach, eine der Bedingungen falsch zu machen oder vollständig zu vergessen, so dass eine Fehlerbedingung ignoriert wird.

Kevin Cline
quelle
4
Ich denke, das ist eigentlich ein ziemlich gutes Argument. Ihr Code ist klar und prägnant und macht Sinn, was er tut. Dies ähnelt dem, was in dem Code passiert, den ich sehe, nur dass es viel komplexer ist, verschachtelt ist und mehr als 30 Codezeilen umfasst.
James P. Wright
@ James: Klingt so, als wäre der Code in Ordnung, wenn Sie einige kleinere Methoden extrahieren würden.
Kevin Cline
1
Man könnte argumentieren, dass Java wirklich so etwas wie C # 's TryParse verwenden könnte. In C # wäre dieser Code int i; if(long.TryParse(s, out i)) return i; else return null;. TryParse gibt false zurück, wenn der String nicht analysiert werden konnte. Wenn es analysiert werden könnte, setzt es das Ausgabeargument auf die Ergebnisse der Analyse und gibt true zurück. Es treten keine Ausnahmen auf (auch nicht intern in TryParse), und insbesondere keine Ausnahmen eines Typs, der Programmiererfehler bedeutet, wie sie in .NETs FormatExceptionimmer angezeigt werden.
Kevin Cathcart
1
@ Kevin Cathcart, aber warum ist das besser? Der Code, der die NumberFormatException abfängt, ist für mich viel offensichtlicher, als das Ergebnis von TryParse auf Null zu prüfen.
Winston Ewert
1
@ ChrisMiskowiec, ich vermute, welche Sie klarer finden, ist so ziemlich eine Frage dessen, was Sie gewohnt sind. Ich finde es viel einfacher, der Ausnahme zu folgen, als nach magischen Werten zu suchen. Aber das ist alles subjektiv. Objektiv denke ich, wir sollten Ausnahmen vorziehen, weil sie einen vernünftigen Standard haben (Absturz des Programms), anstatt einen Standard, der Fehler verbirgt (fahren Sie fort, als wäre nichts passiert). Es ist wahr, dass .NET mit Ausnahmen schlecht abschneidet. Dies ist jedoch ein Ergebnis des .NET-Designs und nicht der Art von Ausnahmen. Wenn Sie mit .NET arbeiten, müssen Sie das tun. Ausnahmen sind aber grundsätzlich besser.
Winston Ewert
12

Debug- und Wartungsarbeiten sind sehr schwierig, wenn der Steuerungsfluss mithilfe von Ausnahmen ausgeführt wird.

Inhärent sind Ausnahmen als Mechanismus zur Änderung des normalen Kontrollflusses Ihres Programms gedacht - zur Durchführung ungewöhnlicher Aktivitäten, die ungewöhnliche Nebenwirkungen hervorrufen, um aus einer besonders engen Bindung herauszukommen, die nicht mit weniger Kompliziertheit bewältigt werden kann meint. Ausnahmen sind außergewöhnlich. Dies bedeutet, dass abhängig von der Umgebung, in der Sie arbeiten, die Verwendung einer Ausnahme für den regulären Steuerungsfluss Folgendes verursachen kann:

  • Ineffizienz Die zusätzlichen Rahmen, durch die die Umgebung springen muss, um die relativ schwierigen Kontextänderungen, die für Ausnahmen erforderlich sind, sicher durchzuführen, erfordern Instrumente und Ressourcen.

  • Schwierigkeiten beim Debuggen Manchmal werden nützliche Informationen (beim Versuch, ein Programm zu debuggen) aus dem Fenster geworfen, wenn Ausnahmen auftreten. Sie können den Überblick über den Programmstatus oder den Verlauf verlieren, der für das Verständnis des Laufzeitverhaltens relevant ist

  • Wartungsprobleme Der Ausführungsfluss ist durch Ausnahmesprünge nur schwer zu verfolgen. Darüber hinaus wird möglicherweise eine Ausnahme aus dem Black-Box-Typcode ausgelöst, der sich beim Auslösen einer Ausnahme möglicherweise nicht so leicht verständlich verhält.

  • Schlechte Entwurfsentscheidungen Programme, die auf diese Weise erstellt wurden, fördern eine Geisteshaltung, die sich in den meisten Fällen nicht leicht auf die elegante Lösung von Problemen übertragen lässt. Die Komplexität des endgültigen Programms hält den Programmierer davon ab, dessen Ausführung vollständig zu verstehen, und ermutigt ihn, Entscheidungen zu treffen, die zu kurzfristigen Verbesserungen mit hohen langfristigen Kosten führen.

Blaubeerfelder
quelle
10

Ich habe dieses Muster schon mehrmals gesehen.

Es gibt zwei Hauptprobleme:

  • Es ist extrem teuer (Instanziierung des Ausnahmeobjekts, Sammeln des Aufrufstapels usw.). Einige Compiler sind möglicherweise tatsächlich in der Lage, es zu optimieren, aber ich würde in diesem Fall nicht damit rechnen, da Ausnahmen nicht für eine solche Verwendung vorgesehen sind. Daher können Sie nicht erwarten, dass die Benutzer es optimieren.
  • Das Verwenden von Ausnahmen für den Kontrollfluss ist in der Tat ein Sprung, ähnlich wie bei a goto. Sprünge gelten aus mehreren Gründen als schädlich. Sie sollten verwendet werden, wenn alle Alternativen erhebliche Nachteile haben. Tatsächlich erinnere ich mich in meinem gesamten Code nur an zwei Fälle, in denen Sprünge eindeutig die beste Lösung waren.
back2dos
quelle
2
Stell es einfach da raus, wenn / else auch als Sprung angesehen wird. Der Unterschied besteht darin, dass es sich um einen Sprung handelt, der nur an dieser bestimmten Stelle stattfinden kann (und viel einfacher zu lesen ist), und dass Sie sich keine Gedanken über die Namen der Etiketten machen müssen (was Sie auch mit try / catch nicht tun müssen) , aber im Vergleich zu goto). Aber nur zu sagen "es ist ein Sprung, der schlecht ist" sagt auch, dass wenn / sonst schlecht ist, wenn es nicht ist.
Sternberg
1
@jsternbarg: Ja, wenn / else tatsächlich zu Sprüngen auf Maschinenebene kompiliert wurde, aber auf Sprachebene ist das Sprungziel die nächste Anweisung, während es sich bei Schleifen um die aktuelle Anweisung handelt. Ich würde argumentieren, dass das eher ein Schritt als ein Sprung ist;)
back2dos
9

Manchmal sind Ausnahmen am schnellsten. Ich habe Fälle gesehen, in denen Nullobjektausnahmen sogar in Java schneller waren als die Verwendung von Kontrollstrukturen (ich kann die Studie derzeit nicht zitieren, daher müssen Sie mir vertrauen). Das Problem tritt auf, wenn Java sich tatsächlich die Zeit nehmen und den Stack-Trace einer benutzerdefinierten Ausnahmeklasse auffüllen muss, anstatt native Klassen zu verwenden (die zumindest teilweise zwischengespeichert zu sein scheinen). Bevor wir sagen, dass etwas einseitig schneller oder langsamer ist, wäre es gut, ein Benchmarking durchzuführen.

In Python ist es nicht nur schneller, sondern auch korrekter, etwas zu tun, das möglicherweise eine Ausnahme verursacht, und dann den Fehler zu beheben. Ja, Sie können ein Typensystem erzwingen, aber das widerspricht der Philosophie der Sprache - stattdessen sollten Sie einfach versuchen, die Methode aufzurufen und das Ergebnis abzufangen! (Testen, ob eine Datei beschreibbar ist, ist ähnlich. Schreiben Sie einfach darauf und stellen Sie den Fehler fest.)

Ich habe Zeiten erlebt, in denen es schneller geht, etwas Dummes wie Abfragetabellen zu tun, die nicht vorhanden waren, als herauszufinden, ob eine Tabelle in PHP + MySQL vorhanden ist (die Frage, bei der ich dies vergleiche, ist eigentlich meine einzige akzeptierte Antwort mit negativen Stimmen). .

Trotzdem sollte die Verwendung von Ausnahmen aus mehreren Gründen eingeschränkt werden:

  1. Versehentliches Verschlucken verschachtelter Ausnahmen. Das ist großartig. Wenn Sie eine tief verschachtelte Ausnahme bemerken, die jemand anderes zu behandeln versucht, haben Sie gerade Ihren Programmierkollegen (vielleicht sogar Sie!) In den Fuß geschossen.
  2. Tests werden nicht offensichtlich. Ein Codeblock, der eine Ausnahme enthält, kann eine der folgenden Ursachen haben: Ein Boolescher Wert dagegen, obwohl es theoretisch ärgerlich sein könnte, Fehler zu beheben, ist dies im Allgemeinen nicht der Fall. Dies gilt insbesondere, da die try...catchKontrollfluss-Teilnehmer im Allgemeinen (meiner Erfahrung nach) nicht der Philosophie "Code in Try-Block minimieren" folgen.
  3. Ein else ifBlock ist nicht zulässig . Genug gesagt (und wenn jemand mit einem "Aber sie könnten verschiedene Ausnahmeklassen verwenden" kontert, lautet meine Antwort "Geh in dein Zimmer und komm nicht raus, bis du über das nachgedacht hast, was du gesagt hast.")
  4. Es ist grammatisch irreführend. Exceptionbedeutet für den Rest der Welt (wie bei Nichtbefolgung der try...catchKontrollflussphilosophie), dass etwas in einen instabilen (wenn auch möglicherweise wiederherstellbaren) Zustand eingetreten ist. Instabile Zustände sind SCHLECHT und es sollte uns alle nachts wach halten, wenn wir tatsächlich vermeidbare Ausnahmen haben (es schreckt mich tatsächlich heraus, keine Lügen).
  5. Es entspricht nicht dem üblichen Codierungsstil. Unsere Aufgabe, sowohl mit unserem Code als auch mit unserer Benutzeroberfläche, ist es, die Welt so offensichtlich wie möglich zu machen. try...catchDer Kontrollfluss widerspricht den allgemein als Best Practices angesehenen Methoden. Dies bedeutet, dass jemand, der noch nicht mit einem Projekt vertraut ist, mehr Zeit benötigt, um sich mit dem Projekt vertraut zu machen.
  6. Dies führt häufig zu Codeduplizierungen. Schließlich müssen Blöcke, obwohl dies nicht unbedingt erforderlich ist, alle baumelnden Zeiger auflösen, die durch den unterbrochenen Versuchsblock offen gelassen wurden. Also versuchen Sie es mit Blöcken. Dies bedeutet, dass Sie eine haben können try{ obj.openSomething(); /*something which causes exception*/ obj.doStuff(); obj.closeSomething();}catch(Exception e){obj.closeSomething();}. In einem traditionelleren if...elseSzenario closeSomething()ist es weniger wahrscheinlich (wiederum persönliche Erfahrung), dass es sich um einen Kopier- und Einfügejob handelt. (Zugegeben, dieses spezielle Argument hat mehr mit Menschen zu tun, denen ich begegnet bin als mit der eigentlichen Philosophie).
cwallenpoole
quelle
AFAIK, # 6, ist nur in Java ein Problem, das im Gegensatz zu jeder anderen modernen Sprache weder Closures noch ein Stack-basiertes Ressourcenmanagement aufweist. Die Verwendung von Ausnahmen ist mit Sicherheit kein Problem.
Kevin Cline
4 und 5 scheinen mir der gleiche Punkt zu sein. 3-6 trifft nicht zu, wenn Ihre Sprache Python ist. 1 und 2 sind potenzielle Probleme, aber ich denke, sie werden durch Minimieren des Codes im try-Block behoben.
Winston Ewert
1
@ Winston Ich bin anderer Meinung. 1 und 2 sind Hauptprobleme, die zwar durch bessere Codierungsstandards gemindert werden, aber dennoch die Frage aufwerfen, ob es nicht besser ist, einfach den potenziellen Fehler zu vermeiden. 3 gilt, wenn Ihre Sprache Python ist. 4-5 kann auch für Python gelten, muss aber nicht. 4 und 5 sind sehr unterschiedliche Punkte - irreführend unterscheidet sich von stilistischen Unterschieden. Irreführender Code kann dazu dienen, den Auslöser so zu benennen, dass ein Fahrzeug mit der Stopptaste gestartet wird. Stilistisch könnte es auch analog dazu sein, alle Blockeinrückungen in C.
cwallenpoole
3) Python hat einen else-Block für Ausnahmen. Es ist enorm hilfreich, um die Probleme zu vermeiden, die normalerweise bei 1 und 2 auftreten.
Winston Ewert
1
Um ganz klar zu sein, ich befürworte nicht, Ausnahmen zu verwenden, die Ihr allgemeiner Flusskontrollmechanismus sind. Ich befürworte das Auslösen einer Ausnahme für jede Art von "Fehler" -Modus, egal wie gering. Ich denke, dass die Version zur Ausnahmebehandlung sauberer ist und weniger wahrscheinlich Fehler verbirgt als die Version zur Überprüfung des Rückgabewerts. Im Idealfall möchte ich, dass Sprachen das Erkennen verschachtelter Fehler erschweren.
Winston Ewert
4

Mein Hauptargument ist, dass die Verwendung von try / catch für die Logik den logischen Fluss unterbricht. Das Verfolgen von "Logik" durch nicht-logische Konstrukte ist (für mich) kontraintuitiv und verwirrend. Ich bin es gewohnt, meine Logik als "Wenn Bedingung dann A sonst B" zu lesen. Die gleiche Aussage wie "Try A catch then execute B" zu lesen, fühlt sich seltsam an. Es wäre noch seltsamer, wenn die Anweisung Aeine einfache Zuweisung wäre und zusätzlicher Code erforderlich wäre, um eine Ausnahme zu erzwingen, wenn sie conditionfalsch ist (und dies würde wahrscheinlich ifohnehin eine -Anweisung erfordern ).

FrustratedWithFormsDesigner
quelle
2

Nun, nur eine Frage der Etikette, bevor ich, wie Sie sagen, "eine Auseinandersetzung mit ihnen anfange", würde ich Sie freundlich fragen: "Warum verwenden sie die Ausnahmebehandlung an all diesen verschiedenen Stellen?"

Ich meine, es gibt mehrere Möglichkeiten:

  1. Sie sind inkompetent
  2. Es gibt einen absolut stichhaltigen Grund für das, was sie getan haben, der vielleicht nicht auf den ersten Blick auftaucht.
  3. manchmal ist es eine Frage des Geschmacks und kann einen komplexen Programmablauf vereinfachen.
  4. Es ist ein Relikt der Vergangenheit, dass sich noch niemand verändert hat und sie würden sich freuen, wenn jemand es tut

... Ich denke, all dies ist gleich wahrscheinlich. Also frag sie einfach nett.

dagnelies
quelle
1

Try Catch sollte nur zur Ausnahmebehandlung verwendet werden. Dies gilt insbesondere für die Behandlung von Ausnahmen. Ihr Versuchsfang sollte nur erwartete Ausnahmen fangen, ansonsten ist er nicht gut geformt. Wenn Sie catch all verwenden müssen, versuchen Sie catch, dann machen Sie wahrscheinlich etwas falsch.

BEARBEITEN:

Grund: Sie können argumentieren, dass, wenn Sie try catch als bedingten Operator verwenden, wie Sie REAL-Ausnahmen berücksichtigen werden?

AJC
quelle
2
Das OP fragt nach Gründen / Argumenten. Sie haben keine bereitgestellt.
Oded
"Sie können argumentieren, dass, wenn Sie try catch als bedingten Operator verwenden, wie Sie REAL-Ausnahmen berücksichtigen werden?" - Indem Sie diese realen Ausnahmen in einer catchKlausel erfassen, die sich von der Klausel unterscheidet, die "nicht reale" Ausnahmen erfasst?
@delnan - Danke! Sie haben einen Punkt bewiesen, den ich machen wollte. Wenn jemand antwortete, was Sie gerade zu meinem und Odeds Grund gesagt haben, würde ich einfach aufhören zu reden, weil er nicht nach Gründen sucht, warum er nur hartnäckig ist, und ich meine Zeit nicht mit Hartnäckigkeit vergeude.
AJC
Du nennst mich bescheuert, weil ich auf Fehler in einigen der hier aufgeführten Argumente hinweise? Beachten Sie, dass ich nichts gegen die hier genannten Punkte zu sagen habe. Ich bin kein Fan von Ausnahmen für die Flusskontrolle (obwohl ich auch nichts ohne Details verurteile, daher meine Frage nach der Ausarbeitung durch OP), ich spiele nur Devil's Advocate.
1
Die Verwendung von try-catch als Bedingungsoperator verhindert in keiner Weise, dass "echte" Ausnahmen abgefangen werden.
Winston Ewert
1

Ausnahme sind, wenn außergewöhnliche Dinge passieren. Funktioniert das Programm gemäß regulärem Workflow außergewöhnlich?

jfrobishow
quelle
1
Aber wieso? Der Punkt der Frage ist, warum (oder warum nicht) Ausnahmen nur dafür gut sind.
Winston Ewert
Nicht immer "außergewöhnlich". Das Nichtfinden eines Schlüssels in einer Hash-Tabelle ist beispielsweise nicht so außergewöhnlich, und dennoch kann die OCaml-Bibliothek in solchen Fällen eine Ausnahme auslösen. Und es ist in Ordnung - die Ausnahmebehandlung ist dort sehr billig.
SK-logic,
1
-1: tautologische Aussage
Reismehl Kekse
1

Grund für die Verwendung von Ausnahmen:

  1. Wenn Sie vergessen, einen außergewöhnlichen Umstand zu erfassen, stirbt Ihr Programm und der Stack-Trace gibt Ihnen genau Auskunft darüber, warum. Wenn Sie vergessen, den Rückgabewert für einen Ausnahmefall zu verarbeiten, wird nicht angegeben, wie weit Ihr Programm ein falsches Verhalten aufweist.
  2. Die Verwendung von Rückgabewerten funktioniert nur, wenn es einen Sentinel-Wert gibt, den Sie zurückgeben können. Wenn alle möglichen Rückgabewerte bereits gültig sind, was werden Sie tun?
  3. Eine Ausnahme enthält zusätzliche Informationen darüber, was passiert ist und was möglicherweise hilfreich ist.

Gründe, keine Ausnahmen zu verwenden:

  1. Viele Sprachen sind nicht dafür ausgelegt, Ausnahmen schnell zu machen.
  2. Ausnahmen, die mehrere Schichten über den Stapel laufen, können einen inkonsistenten Zustand hinterlassen

Schlussendlich:

Ziel ist es, Code zu schreiben, der kommuniziert, was gerade passiert. Ausnahmen können helfen / behindern, je nachdem, was der Code tut. Ein Versuch / Fang in Python für einen KeyError in einer Wörterbuchreferenz ist perfekt (solange Sie die Sprache kennen). Versuch / Fang für denselben KeyError, der fünf Funktionsschichten entfernt ist, ist gefährlich.

Winston Ewert
quelle
0

Ich benutze try-> catch als Flusskontrolle in bestimmten Situationen. Wenn Ihre primäre Logik von etwas abhängt, das fehlschlägt, Sie aber nicht einfach eine Ausnahme auslösen und beenden möchten ... Dafür ist ein try-> catch-Block vorgesehen. Ich schreibe viele nicht überwachte serverseitige Unix-Skripte, und es ist weitaus wichtiger, dass sie nicht scheitern, als dass sie hübsch scheitern.

So versucht Plan A, und wenn Plan A sterben, fängt und lief mit Plan B ... Und wenn Plan B ausfällt, schließlich zu Kick - off Plan C, das wird entweder fix eine der ausgefallenen Dienste in A oder B oder Seite mich.

Satanicpuppy
quelle
0

Dies hängt von der Sprache und möglicherweise von der verwendeten Implementierung ab. Der Standard in C ++ ist, dass Ausnahmen für wirklich außergewöhnliche Ereignisse gespeichert werden sollten. Auf der anderen Seite lautet in Python eine der Richtlinien: " Es ist einfacher, um Vergebung zu bitten als um Erlaubnis ", daher wird die Integration von try / except-Blöcken in die Programmlogik empfohlen.

Charles E. Grant
quelle
"Der Standard in C ++ ist, dass Ausnahmen für wirklich außergewöhnliche Ereignisse gespeichert werden sollten." Das ist schwachsinn. Sogar der Erfinder der Sprache ist anderer Meinung als Sie .
Arayq2
-1

Es ist eine schlechte Angewohnheit, aber ich mache es von Zeit zu Zeit in Python. Anstatt zu prüfen, ob eine Datei existiert, versuche ich einfach, sie zu löschen. Wenn es eine Ausnahme auslöst, fange ich und fahre fort zu wissen, dass es nicht da war. <== (nicht unbedingt wahr, wenn ein anderer Benutzer die Datei besitzt, aber ich mache es in einem Benutzerverzeichnis, so dass dies NICHT passieren SOLLTE).

Überbeansprucht ist es jedoch eine schlechte Praxis.

RobotHumans
quelle
3
In diesem Beispiel ist die Verwendung von Ausnahmen anstelle von "Vor dem Sprung schauen" eine gute Idee: Es werden Rennbedingungen vermieden. Eine erfolgreiche Prüfung der Dateiverfügbarkeit (Existenz, Berechtigungen, nicht gesperrt) bedeutet nicht, dass der Zugriff (Öffnen, Löschen, Verschieben, Sperren, was auch immer) später erfolgreich sein wird, auch wenn es sich nur um ein paar Opcodes handelt dazwischen geändert werden (gelöscht, verschoben, seine Berechtigungen geändert haben).
Wenn Python eine Ausnahme auslöst, nur weil eine Datei nicht existiert, scheint dies zu schlechten Gewohnheiten zu führen, wie Delnan beschreibt.
Per Johansson
@delnan: Obwohl es wahr ist, IMHO, wenn solche Rennbedingungen wahrscheinlich sind, sollten Sie Ihr Design überdenken. In einem solchen Fall fehlt es eindeutig an einer Trennung der Bedenken in Ihren Systemen. Sofern Sie keine guten Gründe haben, dies zu tun, sollten Sie entweder den Zugriff auf Ihrer Seite vereinheitlichen oder eine geeignete Datenbank verwenden, um mehrere Clients zu verwalten, die versuchen, Transaktionen mit denselben persistenten Daten durchzuführen.
back2dos
1
Das ist keine schlechte Angewohnheit. Es ist der empfohlene Stil in Python.
Winston Ewert
@ back2dos, können Sie dies verhindern, wenn Sie mit externen Ressourcen wie anderen Benutzern der Datenbank / des Dateisystems arbeiten?
Winston Ewert
-1

Ich mag die Art und Weise, wie Apple sie definiert : Ausnahmen gelten nur für Programmiererfehler und schwerwiegende Laufzeitfehler. Verwenden Sie ansonsten Fehlercodes. Es hilft mir zu entscheiden, wann ich es verwenden soll, und ich denke mir: "War das ein Programmiererfehler?"

Per Johansson
quelle