2016-10-27 1 views
0

Ich lese einige Quellcode, die eine Funktion ähnlich der folgenden enthält:Verwendung von „außer Exception“ vs. „außer ... raise“ in Python

def dummy_function(): 
    try: 
     g = 1/0 
    except Exception as e: 
     raise Exception("There is an error: {}".format(e)) 

Wie ich es verstehe, alle Ausnahmen sind von der Exception Klasse abgeleitet, so sollte dies alle Fehler erfassen. Folgende https://docs.python.org/3/tutorial/errors.html, dann würde dies

def dummy_function(): 
    try: 
     g = 1/0 
    except: 
     print "There is an error:" 
     raise 

I

nicht gleichwertig sein bemerken, dass die gedruckte Ausgabe in jedem Fall etwas anders angeordnet ist, aber es scheint mir, dass das zweite Verfahren im Grunde genommen die gleichen sind und weniger ausführlich ist. Oder fehlt mir etwas?

+3

Nein, sie sind nicht gleichwertig. Die neue 'Exception'-Instanz hat eine andere Nachricht angehängt. Das ist der springende Punkt beim Re-Raise, um die Botschaft zu ändern. –

+2

Und eine Decke 'except:' fängt 'BaseException' ab und es sind auch Unterklassen, während' except Exception: 'nicht. –

Antwort

5

Nein, das ist der Code nicht äquivalent, aus mehreren Gründen:

  • Eine leere except: Fänge alle Ausnahmen, einschließlich derer, die sich von BaseException (SystemExit, KeyboardInterrupt und GeneratorExit); catching Exception filtert die Ausnahmen aus, die Sie im Allgemeinen vermeiden möchten, ohne ein Re-Raise. In älteren Python-Versionen würde es auch String-Ausnahmen abfangen (nicht mehr erlaubt).
  • Die except Exception as e fängt Subklassen, aber dann löst eine neue Exception() Instanz; Die spezifischen Typinformationen können nicht mehr in den nachgelagerten try...except Anweisungen verwendet werden.
  • In Python 3, schafft eine neue Ausnahme von einer Ausnahmebehandlungsroutine eine Ausnahme Anheben Kette (wobei die ursprüngliche Ausnahme als Attribut Exception.__context__ hinzugefügt wird, siehe Python "raise from" usage)
  • Die Botschaft ist, aktualisiert; das ist wohl der springende Punkt hier, der Ausnahme eine andere Nachricht zu geben.

Der Code, den Sie gefunden haben, ist .. eher schlechte Praxis. Der Exception-Handler der obersten Ebene sollte nur eine Nachricht und möglicherweise eine Trace-Back abfangen und drucken, anstatt die Exception mit einer neuen Nachricht erneut zu erzeugen (und in Python 2 alle Informationen über die ursprüngliche Exception in Python 3 für Ausnahme nicht zugänglich machen) passend in späteren Handlern).

+1

Wenn Sie eine neue Exception auslösen, wird eine Kette von Exceptions erzeugt, während der bare 'raise' nicht – vaultah

+0

@vaultah ist: vorausgesetzt das ist Python 3. –