2017-05-04 11 views
0

Implementieren Sie eine eigene Ausnahmeklasse in Python?
Für jetzt habe ich nicht die Situation, die ich in Schwierigkeiten
ohne Original bekommen. Ich meine, eingebaute Ausnahme ist genug.Implementieren Sie Ihre eigene Exception in Python?

Was wäre der Hauptvorteil der selbst implementierten Ausnahme?

+0

Im Gegensatz zu den meisten anderen Sprachen sind Ausnahmen in Python relativ günstig und werden regelmäßig als verherrlichte GOTO verwendet - oft werden für die Flusskontrolle benutzerdefinierte Ausnahmen verwendet. –

+0

Interessant ... "für Flusskontrolle verwendet" bedeutet benutzerdefinierte Ausnahme wird manchmal für keine außergewöhnliche Situation verwendet? – Pythoner

+0

Ja. Das beste Beispiel ist die 'for'-Schleife: Wenn das iterable erschöpft ist, wird StopIteration ausgelöst. Dies ist nicht außergewöhnlich, das Iterator-Protokoll ist der Kern der Sprache. –

Antwort

3

Im Allgemeinen sollten Sie Ihre eigenen Ausnahmen nur dann definieren, wenn Sie einen bestimmten Fall haben, in dem das Auslösen einer benutzerdefinierten Ausnahme sinnvoller wäre als das Erweitern einer vorhandenen Python-Ausnahme.

Zum Beispiel sagen, dass ich eine Befehlszeilenargument-Parsing-API implementierte, und ich musste den Fall berücksichtigen, in dem ein Benutzer ein ungültiges Befehlszeilenargument eingibt, was auch immer es sein mag. Jetzt kann ich einfach eine Python-Ausnahme wie SyntaxError oder auslösen, aber das wäre eine schlechte Design-Entscheidung.

Ich möchte an den Benutzer zu übermitteln können, warum eine Ausnahme ausgelöst wird, nicht nur, dass eine Ausnahme ausgelöst wird. Eine bessere Option wäre, die allgemeine Ausnahmeklasse Exception zu unterklassifizieren und eine spezifische benutzerdefinierte Ausnahme zu erstellen. Vielleicht InvalidCommandLineArgument.

Jetzt, anstatt eine allgemeine Python-Ausnahme zu verwenden, kann ich meine benutzerdefinierte Ausnahme verwenden, die hilft, den Benutzer klar und prägnant über ihren Fehler zu informieren.

Dies kann auch nützlich sein, wenn Sie informiert werden möchten, wenn eine bestimmte Aktion in Ihrem Code fehlschlägt. Wenn Sie z. B. eine Funktion zum Herunterladen einer Zertifikatsdatei aus dem Internet erstellen, kann sie eine Ausnahme vom Typ NoInternetConnection auslösen, um Sie darüber zu informieren, wenn die Internetverbindung unterbrochen ist. Auf diese Weise können Sie eine bestimmte Aktion basierend auf der ausgelösten Ausnahme ausführen.

Jetzt können Sie sich fragen, warum im zweiten Fall Sie nicht einfach eine bedingte Anweisung zu Test verwenden können, wenn es eine Internetverbindung gab, bevor Sie versuchen, es zu verwenden. Der Grund, warum Sie sich für das Spätere entscheiden, liegt darin, dass das Motto in Python lautet: "Um Vergebung zu bitten, ist einfacher, als um Erlaubnis zu bitten." Dies bedeutet, dass es einfacher ist, Python zu fragen, ob eine Ausnahme ausgelöst werden soll, als wenn versucht wird, alle möglichen Fehler mit bedingten Anweisungen zu umgehen.

Am Ende, es ist nicht über „ Haben Sie Ihre eigenen Ausnahmen in Python implementieren?“, Sondern „Wenn sehen Sie Ihre eigenen Ausnahmen in Python implementieren?“

+0

Vielen Dank. Jetzt hab ich es verstanden. Wir müssen dem Benutzer vermitteln, warum eine Ausnahme ausgelöst wird, und manchmal eine bestimmte Aktion basierend auf der Art der Ausnahme ergreifen. Ich behalte das auch im Kopf: "Um Vergebung zu bitten, ist einfacher als nach Erlaubnis zu fragen". – Pythoner

+0

Ich bin froh, dass ich dir helfen konnte, besser zu verstehen, @Daichi. Vielleicht möchten Sie auch mehr über Ausnahmen in der [offiziellen Python-Dokumentation] lesen. (Https://docs.python.org/3/library/exceptions.html) –

1

Es ist nützlich, wenn Sie eine bestimmte Art von Ausnahme abfangen wollen, die Sie machen. Sie wollen nie nur "Exception" erfassen, weil Sie möglicherweise eine andere Ausnahme erfassen, von der Sie nichts wissen.

+0

Während ich verstehe, was du zu sagen versuchst, glaube ich nicht, dass du einen sehr guten Punkt machst. Ihr Recht, dass Sie die Basisausnahmeklasse nicht verwenden sollten. Sie könnten wichtige Fehler maskieren. _But_ Sie sollten auch nicht nur eigene Ausnahmen erstellen. Wenn Python bereits einen Fehler verursacht, ist es sinnlos, auch einen eigenen Fehler zu erstellen. Das ist überflüssig. Ermitteln Sie stattdessen die genauen Fehler, die Ihr Code verursachen könnte, und berücksichtigen Sie stattdessen diese spezifischen Fehler. –

+0

Ich habe mehr darüber nachgedacht, dass es eine gute Möglichkeit ist, Fehler in Ihrem Code durch unerwartete Fehler zu vermeiden.Wenn Ihr Code beispielsweise einen ValueError auslöst und ihn irgendwo anders abfängt, verpassen Sie möglicherweise einen anderen Ort, an dem eine andere Bibliothek ihren eigenen ValueError wirft. Sicher - in einer idealen Welt würden Sie einfach keinen Code schreiben, der Fehler verursacht, aber es ist keine ideale Welt. – Arya

1

Mit benutzerdefinierten Ausnahmen können verschiedene Arten von Fehlern eindeutig unterschieden werden. Vergleichen

class NumberTooBig(ValueError): 
    pass 

class NumberTooSmall(ValueError): 
    pass 

try: 
    ... 
except NumberTooBig: 
    ... 
except NumberTooSmall: 
    ... 

mit

try: 
    ... 
except ValueError as exc: 
    if str(exc) == "too big": 
     ... 
    elif str(exc) == "too small": 
     ... 
    else: 
     # A different ValueError I don't know how to handle 
     raise exc 

Mit benutzerdefinierten Ausnahmen, betten Sie Informationen über den Fehler in der Art der Ausnahme selbst, die es leichter zu fangen macht nur den spezifischen Fehler Sie wollen, ohne sich zu erinnern um versehentlich aufgefundene Fehler erneut zu beheben.

+0

Vielen Dank für Ihr konkretes Beispiel! – Pythoner

2

Zollausnahmen werden am besten verwendet, wenn Sie Informationen an andere Personen weitergeben möchten, die Ihren Code anrufen, damit sie herausfinden können, was zu tun ist.

Zum Beispiel:

Lassen Sie uns sagen, dass ich ein Modul pet_store schrieb, die eine get_dog(type) Funktion zur Verfügung gestellt und Sie es genannt.

Wenn ich die Funktion schreiben, könnte es bestimmte Möglichkeiten, die dies nicht gelingen könnte:

NoDogsLeftException # Sold out of all dogs 
NoDogsOfBreedException # Sold out of that breed 
OwnerHouseCheckException # We checked your house and it's disgusting. Clean up you slob 

Wenn Sie nun import pet_store und pet_store.get_dog("chihuahua"), ich könnte ein NoDogsOfBreedException werfen ..., weil ich weiß nicht, was Sie möchten in diesem Fall tun.

Einige Leute möchten vielleicht eine andere Rasse versuchen, die keinen Sinn ergeben würde, wenn nur ein Chihuahua Sie befriedigen würde. Das würde auch keinen Sinn ergeben, wenn ich einen OwnerHouseCheckException werfe. Wenn ich sage, dass dein Haus zu dreckig für einen Hund ist, ändert das nicht die Frage nach einer anderen Rasse. Aber es sind genug Informationen, um etwas zu unternehmen.

Welches ist die richtige Art und Weise der Dinge ist: lassen, wer Sie herausfinden, ruft was zu tun ist, wenn eine Ausnahme auftritt

Vielleicht Sie wollen:

  • Retry
  • einen anderen Versuchen Abfrage
  • Zeigen Sie eine Nachricht an Ihren Benutzer
  • Spin ein neuer Server bis
  • Starten einer Rakete
  • Lassen Sie die

Der Punkt Hunde ist: Ich weiß nicht,, was das Richtige zu tun, ist in Ihrem Programm. Und das Richtige für dich könnte anders sein als andere. Stattdessen werde ich sagen: "Das ist falsch gelaufen, mach was du mit dieser Information machen willst."

Einige Programme können komplett ohne Internet-Zugang (Diablo III) ausfallen, während andere es schaffen, offline zu sein (Starcraft). Diese Programme reagieren unterschiedlich auf eine NoInternetException.

+0

Die Liste ist sehr hilfreich (und lustig) für mich! Vielen Dank. Ich habe immer nur eine Nachricht angezeigt. Jetzt kann ich je nach Situation mehr tun. – Pythoner

Verwandte Themen