2010-12-12 9 views
19

Wenn ich meine eigenen Exceptions in meinen Python-Bibliotheken erstelle, zeigt der Exception-Stack die Raise-Line selbst als letztes Element des Stacks an. Dies ist offensichtlich kein Fehler, ist konzeptuell richtig, zeigt aber den Fokus auf etwas, das nicht für das Debuggen nützlich ist, wenn Sie Code extern, z. B. als Modul, verwenden.Keine Python-Raise-Zeile im Exception-Stack anzeigen

Gibt es eine Möglichkeit, dies zu vermeiden und Python zwingt das vorherige zu letztem Stapelobjekt als die letzten zu zeigen, wie die Standard-Python-Bibliotheken.

+7

Die Raise-Zeile wird ausgeblendet, wenn sie aus kompiliertem C-Code aufgerufen wird (da keine Raise-Zeile angezeigt wird). Python-Teile der Standardbibliotheken zeigen weiterhin die raise-Anweisung in einem Traceback. –

+0

Vielleicht könnten Sie 'sys.excepthook' hacken, um die letzte Zeile auszuschließen, wenn es sich um eine' Raise' handelt. Aber generell nicht möglich, gewöhne dich dran. – delnan

+4

Sie könnten immer nur eine nützliche Ausnahme auslösen. –

Antwort

7

Warnung: Das Ändern des Verhaltens des Interpreters ist in der Regel verpönt. Und in jedem Fall kann es hilfreich sein, zu sehen, wo genau ein Fehler aufgetreten ist, was das Debugging betrifft, insbesondere wenn eine Funktion aus mehreren verschiedenen Gründen einen Fehler auslösen kann. Wenn Sie das Modul traceback verwenden und sys.excepthook durch eine benutzerdefinierte Funktion ersetzen, ist es wahrscheinlich möglich, dies zu tun. Die Änderung wird sich jedoch auf die Fehleranzeige für das gesamte Programm und nicht nur auf das Modul auswirken. Dies wird wahrscheinlich nicht empfohlen.

könnten Sie auch setzen Code in try aussehen/except Blöcke, dann den Fehler zu modifizieren und neu zu erhöhen es. Aber Ihre Zeit ist wahrscheinlich besser damit verbracht, unerwartete Fehler unwahrscheinlich zu machen und informative Fehlermeldungen für diejenigen zu schreiben, die auftreten könnten.

-1

Ich würde vorschlagen, nicht die Ausnahme-Mechanismus verwenden Argumente zu überprüfen, so verlockend das ist. Das Codieren mit Ausnahmen als Bedingung ist wie das Sprichwort "crash my app, wenn ich als Entwickler nicht an all die schlechten Bedingungen denke, die meine bereitgestellten Argumente verursachen können. Vielleicht die Verwendung von Ausnahmen für Dinge, die nicht nur außerhalb Ihrer Kontrolle liegen, sondern auch unter Kontrolle von etwas anderes wie das Betriebssystem oder die Hardware oder die Python-Sprache wäre logischer, weiß ich nicht.In der Praxis jedoch verwende ich Ausnahmen, wie Sie eine Lösung für.

Um Ihre Frage zu beantworten, teilweise, es ist genauso einfach thusly zu kodieren:

class MyObject(object): 
    def saveas(self, filename): 
     if not validate_filename(filename): 
      return False 
     ... 

Anrufer

if not myobject.saveas(filename): report_and_retry() 

Vielleicht keine gute Antwort, nur etwas zum Nachdenken.

+0

Ich musste dies aufwerten, da ich so viele Ausnahmen wie möglich vermeide und meinem Programm nur befehle, damit umzugehen, darüber zu gehen, das Problem zu protokollieren und weiterzugehen. Ich hatte hier mehr Debugging-Erfolg als mit Ausnahmen überall zu werfen, wie alle anderen ... im Grunde benutze ich print() anstatt zu erhöhen – Tcll

+0

Ich habe gerade an die andere Seite gedacht, und wahrscheinlich der Grund Die meisten würden dies ablehnen (ich werde es immer noch nicht tun, da mein letzter Kommentar immer noch steht), die meisten guten Entwickler werfen nicht einfach Ausnahmen für fast jeden falschen Anwendungsfall, nur bestimmte Fälle, die eine Ausnahme verdienen, erhalten eine Gehaltserhöhung ... gewährte das oben genannte kann in bestimmten Fällen immer noch passieren, nicht einmal Ihr Code würde fangen. zB: Dateiname ist ein Objekt, das eine str repräsentiert. – Tcll

4

Sie können Ihren eigenen Ausnahme-Hook in Python erstellen. Unten ist das Beispiel von Code, den ich verwende.

import sys 
import traceback 

def exceptionHandler(got_exception_type, got_exception, got_traceback): 
    listing = traceback.format_exception(got_exception_type, got_exception, got_traceback) 
    # Removing the listing of statement raise (raise line). 
    del listing[-2] 
    filelist = ["org.python.pydev"] # avoiding the debuger modules. 
    listing = [ item for item in listing if len([f for f in filelist if f in item]) == 0 ] 
    files = [line for line in listing if line.startswith(" File")] 
    if len(files) == 1: 
     # only one file, remove the header. 
     del listing[0] 
    print>>sys.stderr, "".join(listing) 

Und unten sind einige Zeilen, die ich in meinem benutzerdefinierten Ausnahmecode verwendet habe.

sys.excepthook = exceptionHandler 
raise Exception("My Custom error message.") 

Bei dem Verfahren Ausnahme können Sie Dateinamen oder Modulnamen in der Liste „Dateinamen“ hinzufügen, wenn Sie alle unerwünschten Dateien ignoriert werden sollen. Da ich das Python-Pydev-Modul ignoriert habe, da ich Pydev-Debugger in Eclipse verwende.

Das obige wird in meinem eigenen Modul für einen bestimmten Zweck verwendet. Sie können es ändern und für Ihre Module verwenden.