Dieses spezielle Beispiel bezieht sich auf Django in Python, sollte aber auf jede Sprache angewendet werden, die Ausnahmen unterstützt:
%Vor%Die Django-Modellklasse bietet eine einfache Methode get , die es mir ermöglicht, nach einem und nur einem Objekt aus der Datenbank zu suchen, wenn es mehr oder weniger findet Ausnahme. Wenn null oder mehr mit einer alternativen Filter -Methode gefunden werden kann, die eine Liste zurückgibt:
%Vor%Bin ich Ausnahmen zu sehr abgeneigt? Mir scheint die Ausnahme ein wenig verschwenderisch zu sein, bei einer Vermutung wird ein Viertel bis eine Hälfte der Zeit "außergewöhnlich" sein. Ich würde viel lieber eine Funktion bevorzugen, die bei einem Fehler None zurückgibt. Wäre es besser, Djangos Filter Methode zu verwenden und die Liste selbst zu bearbeiten?
Der Hinweis ist im Namen - Ausnahmen sollten außergewöhnlich sein.
Wenn Sie immer erwarten, dass der Artikel existiert, dann verwenden Sie get
, aber wenn Sie erwarten, dass es nicht zu einem vernünftigen Anteil der Zeit existiert (dh es ist nicht ein erwartetes Ergebnis, sondern ein außergewöhnliches Ergebnis), dann würde ich schlage vor, filter
zu verwenden.
Wenn man also annimmt, dass zwischen 1 in 2 und 1 in 4 zu erwarten ist, würde ich definitiv einen Wrapper um filter
schreiben, da dies definitiv kein Ausnahmefall ist.
Glauben Sie es oder nicht, das ist tatsächlich ein Problem, das in jeder Sprache ein bisschen anders ist. In Python werden Ausnahmen regelmäßig für Ereignisse ausgelöst, die nicht von der Sprache selbst als außergewöhnlich angesehen werden. Daher denke ich, dass die Regel "Sie sollten Ausnahmen nur unter außergewöhnlichen Umständen auslösen" nicht ganz zutrifft. Ich denke, dass die Ergebnisse, die Sie in diesem Forum erhalten, angesichts dieser hohen Anzahl von .Net-Programmierern in diese Richtung verschoben werden (siehe diese Frage ) für weitere Informationen dazu).
Zumindest sollte ich niemanden fangen, der sich an diese Regel hält, jemals einen Generator oder eine for-Schleife in Python zu verwenden (beide beinhalten das Werfen von Ausnahmen für nicht-außergewöhnliche Umstände).
In Programmiersprachen gibt es eine große Spaltung in Bezug auf die Verwendung von Ausnahmen.
Die Mehrheitsansicht besagt, dass Ausnahmen außergewöhnlich sein sollten . In den meisten Sprachen mit Ausnahmen ist die Übertragung der Kontrolle durch die Ausnahme erheblich teurer als beispielsweise durch die Rückgabe der Prozedur.
Es gibt eine starke Minderheitssicht, dass Ausnahmen nur ein anderes Kontrollfluss-Konstrukt sind, und sie sollten billig sein. Der Standard ML von New Jersey und Objective Caml Compiler abonnieren diese Ansicht. Wenn Sie billige Ausnahmen haben, können Sie einige raffinierte Backtracking-Algorithmen auf eine Weise codieren, die mit anderen Mechanismen schwieriger sauber zu codieren ist.
Ich habe diese Debatte wiederholt für neue Sprachdesigns gesehen, und fast immer entscheidet der Gewinner, dass Ausnahmen teuer und selten sein sollten. Wenn Sie Wert auf Leistung legen, sollten Sie dies mit Bedacht programmieren.
Ich stimme der anderen Antwort zu, aber ich wollte hinzufügen, dass die Ausnahme, die so vergeht, Ihnen einen bemerkenswerten Leistungseinbruch beschert. Es wird dringend empfohlen, dass Sie überprüfen, ob das Ergebnis vorhanden ist (falls dies der Filter tut), anstatt Ausnahmen zu übergeben.
Bearbeiten:
Als Antwort auf die Anfrage nach Zahlen habe ich diesen einfachen Test durchgeführt ...
%Vor%Und die Ausgabe war ..
%Vor%HTH.
Die Antwort hängt von der Absicht des Codes ab. (Ich bin mir nicht sicher, was Ihr Code-Sample machen sollte, der Pass im Ausnahmefall ist verwirrend, was wird der Rest des Codes mit object
variable machen?)
Ob man Ausnahmen verwendet oder eine Methode verwendet, die den Fall als nicht-außergewöhnlich behandelt, ist in vielen Fällen Geschmackssache. Wenn der echte Code in der Klausel "except" so kompliziert ist wie die Filtermethode, die Sie verwenden müssen, um die Ausnahme zu vermeiden, verwenden Sie die Filtermethode. Einfacherer Code ist besserer Code.
Abneigung gegen Exzpektionen ist eine Frage der Meinung - wenn jedoch Grund zu der Annahme besteht, dass eine Funktion oder Methode viele Male aufgerufen wird oder schnell aufgerufen wird, führen Ausnahmen zu einer signifikanten Verlangsamung. Das habe ich aus meiner vorherigen Frage gelernt, wo ich mich vorher auf einen geworfenen verlassen musste exception, um einen Standardwert zurückzugeben, statt eine Parameterüberprüfung durchzuführen, um diesen Standardwert zurückzugeben.
Natürlich können Ausnahmen aus irgendeinem Grund noch existieren, und Sie sollten keine Angst haben, wenn nötig einen zu verwenden oder zu werfen - besonders solche, die möglicherweise den normalen Fluss der aufrufenden Funktion unterbrechen könnten.
Ich stimme den obigen Kommentaren nicht zu, dass eine Ausnahme in diesem Fall ineffizient ist, insbesondere da sie in einer I / O-gebundenen Operation verwendet wird.
Hier ist ein realistischeres Beispiel, das Django mit einer SQL-In-Memory-Datenbank verwendet. Jede von 100 verschiedenen Abfragen wurde ausgeführt und dann für jeden von 100 Durchläufen gemittelt. Obwohl ich bezweifle, ob es wichtig wäre, habe ich auch die Reihenfolge der Ausführung geändert.
%Vor%Sie können dies in Ihrer eigenen Django-Umgebung instrumentieren, aber ich bezweifle, dass Ihre Zeit gut dafür genutzt wird, diese Ausnahme zu vermeiden.
Eine Ausnahme sollte nicht verwendet werden, um Informationen von einem Teil des Codes an einen anderen zu übergeben. Es sollte Informationen über die irreguläre Situation selbst enthalten und den Code an den sichersten Punkt zurückgeben, damit die Ausführung fortgesetzt werden kann.
Wenn Sie eine Datei lesen wollen, ist Datei nicht vorhanden eine Ausnahme, Datei zu lang könnte eine Ausnahme sein, wenn Ihr Puffer zu kurz ist und das Lesen eine Ausnahme auslöst. Dies könnte jedoch ersetzt werden, indem zuerst die Dateilänge gelesen und der Status FileTooLong zurückgegeben wird.
Wann Sie was tun: Sie zählen immer darauf, wie teuer eine Ausnahme wirklich ist und wie oft Ihre irreguläre Situation passiert. Wenn Sie sicher sind, dass eine Ausnahme gelegentlich ausgelöst wird, selbst in einem sehr unregelmäßigen Systemstatus, ist es in Ordnung, sie zu verwenden. Wenn Sie wissen, dass es häufiger passieren kann und Sie einen bestimmten Parameter haben, der es unterstützt, wie wir nicht mehr als 50 Ausnahmen auf unserer Website pro Sekunde haben möchten, dann verwenden Sie es nicht.
Was kann schiefgehen? ist eine spezielle Software-Prüfungsaufgabe, weil Sie Ihren Code tatsächlich in unbekannte, zwischen Bestien von Effekten werfen, wenn alles kann und passieren wird.
Es ist schwierig, jedes dieser Szenarien auf industrieller Ebene zu untersuchen, und wir akzeptieren im Allgemeinen, dass einige Ausnahmen, die das System verursacht, von uns eingefangen oder ignoriert werden. Wenn wir jedoch erwägen, selbst eine Ausnahme auszulösen, ist die obige Analyse entscheidend. Wenn Sie sich nicht sicher sind, wie teuer eine Ausnahme ist, wie überwältigend sie für das System ist und wie oft sie im schlimmsten Fall ausgelöst werden kann, dann verwenden Sie sie nicht.
Vergessen Sie nicht, dass jemand, der eine Ausnahme wirft, sie fangen muss. Es besteht immer die Gefahr, dass man sich einfach nicht bewusst ist, dass ein Teil des Codes eine Ausnahme auslöst, wenn er tatsächlich alles durchbrennt und abstürzt.
Neben dem Auslösen einer Ausnahme muss also ein bestimmter Empfangs- und Empfangspunkt für eine Ausnahme vorhanden sein, da eine Ausnahme nur ein Kanal ist. Wenn eine Ausnahme nicht lokal abgefangen wird, muss, auch wenn sie direkt außerhalb der lokalen Funktion abgefangen wird, ein eindeutiger Hinweis darauf vorliegen, dass die Funktion eine Ausnahme auslöst. Dies wird nicht von allen Sprachen unterstützt.
In jeder Sprache sollte das Reduzieren des von der Ausnahme eingeschlossenen Codeumfangs ebenfalls das Ziel sein.
Es ist sehr üblich, einen Teil des Codes mit nur einem try-catch-Block zu umhüllen und dann Ausnahmen zu filtern. Dies muss Gewicht gegen Versuch haben, jedes Segment einzeln zu fangen. Wenn Sie zu viele try-catch-Blöcke haben, verringert dies definitiv die Lesbarkeit. Wenn Sie einen großen try-catch haben, werden die verschiedenen Gründe für Ausnahmen in einer nicht verwandten Weise aufgelistet, es wird schwierig zu verstehen, welcher Teil des Codes die aktuelle Ausnahme ausgelöst hat, was das Debugging und das Lesen des Codes schwieriger macht. Hier ist einer der Parameter die logische Konsistenz des Codes. Wenn es verstopft ist, dass Sie viele Ausnahmen kombinieren müssen, dann muss der Zweck dieses Teils des Codes untersucht werden, da es architektonisch eine Kreuzung ist, die andere Probleme verbergen kann.