2013-07-16 10 views
5

Ich würde gerne wissen, wie ist der Standard Weg (wenn es welche gibt), um die Ausnahmen, die ein Modul/Funktion ausgelöst werden kann.Wie finden Sie Ausnahmen, die für ein bestimmtes Modul in Python ausgelöst werden können?

Nehmen wir zum Beispiel json. Natürlich ging ich auf die Documentation, aber ich fand keine standardisierte Möglichkeit zu wissen, welche Ausnahmen in bestimmten Funktionen ausgelöst werden können (wie dump oder load). Es ist mir nicht klar (auf den ersten Blick), ob es genügt, nur TypeError zu fangen.

Was sind die Empfehlungen, um sicherzustellen, dass wir alles (und gerade genug) über ein bestimmtes Modul/eine bestimmte Funktion erfassen?

+0

Hinweis: In der Dokumentation wird auch 'ValueError' erwähnt. – torek

Antwort

3

Ich war nie völlig mit Pythons Ausnahme Zeug zufrieden. Es funktioniert gut in der Praxis, es ist die Theorie, die mich stört. :-) Vor allem, weil alles dynamisch ist, auch wenn Sie wissen, dass evil() nur ZorgError selbst auslöst und spam() aufruft, was EggsError auslöst, so dass Sie höchstens diese beiden Fehler von einem Anruf an evil() bekommen, könnte jemand Dinge hinter Ihrem Rücken verpatzen und ändere das.

Das heißt, einige Dokumentation ist besser als andere. Zum Beispiel os.kill kann offensichtlich OSError erhöhen, wenn die kill fehlschlägt, und TypeError, wenn Sie es mit etwas anderes als zwei Ganzzahlen nennen, aber wussten Sie, dass es auch OverflowError auslösen kann?

>>> os.kill(9999999999999, 0) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OverflowError: signed integer is greater than maximum 

Wenn Sie versuchen, vernünftig kugelsicheren Code zu schreiben, Dinge wie zu Lesen hat eine pid-Datei und die Sonde, um zu sehen, ob ein Prozess ausgeführt wird, stellt sich heraus Sie diese OverflowError falls fangen die pid in der PID-Datei ist eine ganze Zahl, aber ist außerhalb des Bereichs. Es wäre schön, wenn dies in der Dokumentation (ich fand es durch Folter-Tests statt.)

einfach alles zu kontrollieren (except: oder except Exception) ist in der Regel nicht geeignet, da es in der Regel zu viel fängt (einschließlich zB RuntimeError aus ein Stapelüberlauf). Woher weißt du, was du fangen kannst? Ich denke, dass es schön sein könnte, wenn Blattfunktionen in Standardbibliotheken eine "Exceptions I Raise Direct" -Attribut- oder -Dokumentation-Anforderung haben, aber es ist einfach nicht da.


Edit: Ich oben in einem Kommentar darauf hingewiesen, dass die json Dokumentation ValueError ausdrücklich erwähnt. Nicht explizit genannt, aber in Json's Selbsttests gefunden, sind UnicodeDecodeError (was offensichtlich ist, sobald Sie darüber nachdenken) und AttributeError (nicht so offensichtlich). Die Dokumentation erwähnt auch, dass Sie eine OverflowError erhalten können.Wenn Sie json.dump verwenden, die einen Stream zum Schreiben benötigt, können Sie natürlich auch alle Fehler des Streams erhalten. Dies ist der Grund, warum eine "Liste von Ausnahmen zorg() direkt erhöht" nicht immer sehr nützlich ist.

+0

Ich schätze Ihre Antwort. Es ist ziemlich klar, wie man eine Ausnahme übersehen kann. In Anbetracht dessen, was ist der übliche pythonische Ansatz? Wenn es eine Funktion ist, wie wir 'os.kill' fangen, was auch immer die Dokumentation sagt und einfach die Ecke Fälle verlassen? Und für nicht schön-gut dokumentierte Module wie 'json', fang einfach mit' Exception'? –

+0

Ich bin mir nicht sicher über "gemeinsame Pythonic". Es gibt mehrere Probleme zu beachten. Manchmal ist der Ort, an dem ein Fehler auftritt, relativ hoch. Daher sollten Sie nur die Routinen mit niedrigerer Ebene fehlschlagen lassen und den Fehler weiterleiten. Manchmal ist der Ort, an dem ein Fehler auftritt, richtig, wenn er auftritt. Manchmal besteht das Objekt nicht darin, den Fehler zu "fangen", sondern eher aufzuräumen (z. B. eine Datenstruktur zu entsperren), in welchem ​​Fall ein "try" -Block mit einem "finally" - oder "with" -Stil-Kontext gewünscht wird Manager. Ich habe jedoch einen allgemeinen Konsens gefunden, dass "außer Ausnahme" selten richtig ist. – torek

2

Nun können Sie die globale Typ verwenden Exception-catch die Exceptions:

try: 
    1 + "2" 
except Exception as error: 
    print "Error", error 

Der Ausgang wird etwas wie:

Error unsupported operand type(s) for +: 'int' and 'str' 

Wenn Sie den Namen der Ausnahme wissen wollen, können Sie etwas tun wie:

try: 
    1 + "2" 
except Exception as error: 
    print error.__class__.__name__, error 

und th Die Ausgabe wird etwas wie sein:

TypeError unsupported operand type(s) for +: 'int' and 'str' 
+0

Vielen Dank für die Veröffentlichung einer praktischen Möglichkeit, Ausnahmennamen zu erhalten. Das Hauptproblem ist, dass ich nicht den 'code' in advanced habe, um zu wissen, welche Ausnahmen ausgelöst werden können. Ich dachte nur, ich könnte einen Weg finden, um eine erschöpfende Ausnahmedokumentation über ein bestimmtes Modul zu erhalten. –

+0

Gern geschehen, ich denke, so ist es gut, 'Exceptions' zu fangen, weil manchmal das Dokument eines Moduls schlecht ist oder man manchmal nicht die Art von' Exception' kennt, die eine Bibliothek auslösen kann. –

Verwandte Themen