2009-04-16 10 views

Antwort

25

Es wird als gute Praxis angesehen, das Exception-Stammobjekt normalerweise nicht abzufangen, sondern stattdessen spezifischere Objekte abzufangen, z. B. IOException.

Berücksichtigen Sie, ob eine Ausnahme wegen zu wenig Arbeitsspeicher aufgetreten ist - die Verwendung von "pass" wird Ihr Programm nicht in einem guten Zustand belassen.

So ziemlich die einzige Zeit, die Sie fangen sollten Exception befindet sich auf der obersten Ebene Ihres Programms, wo Sie es protokollieren, einen Fehler anzeigen und so elegant wie möglich beenden können.

+2

diese schlechte Angewohnheit wird auch erhebliche Debugging Alpträume generieren.Vor allem, wenn andere Ausnahmen als die, an die Sie gedacht haben, innerhalb Ihres try/except ausgelöst werden. Und das passiert einfach ... – vaab

3

weil es denkt, dass Sie zu viel fangen. und es ist richtig.

1

Ausnahme wird ausgelöst, wenn etwas ... außergewöhnliches auftritt. Es ist generell eine gute Sache, dass das Programm beendet wird.

Sie möchten vielleicht einige Ausnahmen ignorieren, aber IMO gibt es keinen guten Grund, eine Basisklasse wie diese zu fangen.

+4

Hey. Ich glaube nicht, dass ich zustimme, dass "es keinen guten Grund gibt" - ich kann mir zum Beispiel ein GUI-Programm vorstellen, das eine Ausnahme auslöst, wenn eine bestimmte Operation an einem besonders kniffligen Datensatz versucht wird. Es ist alles gut und gut als Programmierer zu sagen, dass eine unerwartete Ausnahme das Programm mit einem Stack-Trace beenden sollte (früh fehlschlagen), aber in der Praxis, was der Benutzer will ist für den aktuellen Vorgang ordnungsgemäß fehlgeschlagen, möglicherweise mit einer Messagebox oder Logfile Nachricht und dann für die GUI weiter zu arbeiten, so dass sie z speichern Sie ihre Daten, bevor etwas anderes passiert. –

+1

Ich stimme völlig zu, ich bezog mich auf die Art, wie das OP Ausnahmen mit "pass" ignoriert. Ich hätte meinen Standpunkt deutlicher machen sollen. –

+0

Bitte um Verzeihung, fair genug dann. –

-1

Catching Exception (ohne Re-Raising) hat 2 wirklich schlechte Nebenwirkungen: Fehler werden gegessen, so verlieren Sie die Stack-Trace, sondern auch, dass Ctrl-C (oder was auch immer die Break-Taste auf Ihrem Betriebssystem ist) hier behandelt.

Das typische Verhalten von Programmen wie diesem besteht darin, dass sie entweder nicht angehalten werden können oder dass ctrl-c bewirkt, dass der Steuerungsfluss vorwärts (zum Ausnahmebehandler) springt und dann fortfährt. Dann kann entweder der Code nicht unterbrochen werden, oder Sie müssen auf ctrl-c hämmern, um es zu stoppen.

+2

Dies gilt ab Python 2.6 nicht mehr, KeyboardInterrupt erbt nicht mehr von Exception. –

+0

Sie verlieren den Stack-Trace nicht. Verwenden Sie einfach das Traceback-Modul mit sys.exc_info(). – PeqNP

15

Es ist eine gute Übung, nur einen sehr schmalen Bereich von Typen zu erfassen. "Exception" ist zu allgemein - Sie werden nicht nur die Fehler erfassen, die Sie geplant haben, sondern auch andere Fehler, die Bugs in Ihrem Code verbergen können, die schneller diagnostiziert werden könnten, wenn sie überhaupt nicht erfasst werden oder dies möglicherweise tun würden besser mit einem einzelnen Exception-Handler behandelt werden.

Seit Python2.6 ist das Abfangen von Exception viel sinnvoller geworden, weil alle Exceptions, die Sie nicht abfangen wollen (SystemExit, KeyboardInterrupt) nicht mehr von Exception erben. Sie erben stattdessen stattdessen von einer allgemeinen BaseException. Dies wurde absichtlich gemacht, um den Ausnahmefall relativ unschädlich zu machen, da es sich um ein so allgemeines Idiom handelt.

Siehe PEP 3110 für Details & Zukunftspläne.

0

wie Gregs Antwort, "Exception" ist eine Basisklasse und Ausnahmen sollten von dieser Klasse abgeleitet werden, siehe auch exceptions.Exception.

Hier ist eine sehr nützliche Liste der Fehler in pydocs

Beachten Sie auch das sehr praktisch Zurückverfolgungsmodul, das Sie herausfinden kann, wo die Ausnahme aufgetreten. Wenn Sie nur 'except: ...' verwenden, wird Ihnen angezeigt, welchen Fehler Sie in Ihrem Fall am besten verwenden sollten. Zum Beispiel, versuchen Sie diesen Code (toggeln Sie den Kommentar), vielleicht werden Sie es akzeptieren:

import traceback 
#absent = 'nothing' 
try: 
    something = absent 
except NameError: 
    traceback.print_exc() 
else: 
    print("you get here only when you uncomment 'absent'")