Exception abschalten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Ich bastle grad ein Mini-Tool zum Auswerten von Textfiles... Nun hab ich mir grad fein angewöhnt, Programmabstürze mit Exceptions abzufangen... und schon hab ich Probleme beim Weiterentwickeln:

Code: Alles auswählen

def foo():
    doSomething

try:
    foo()
except:
    print "something went wrong"
Wenn ich im oberen Beispiel z.B. durch einen Tippfehler in der Funktion 'foo()' einen Fehler auslösen würde, krieg ich den in der Konsole nicht mehr zu Gesicht, weil das allgemeine 'except'-Statement eingreift und die Python-Fehlerausgabe unterdrückt. Die Fehlersuche gestaltet sich sehr schwierig. Ich würde gern innerhalb der Funktion 'foo()' wieder Python-Fehler erhalten oder mir zumindest den Fehlerverursacher ausgeben lassen. Also sowas hier in etwa:

Code: Alles auswählen

try:
    foo()
except errorCode:
    print "something went wrong: %s" % errorCode
Gibt's natürlich nicht, aber gibt's was äquivalentes?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

droptix hat geschrieben:Gibt's natürlich nicht, aber gibt's was äquivalentes?
Klar:

Code: Alles auswählen

try:
    foo()
except IOError:
    print 'IOError was found'
Deswegen haben die Exceptions ja auch Namen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

droptix hat geschrieben:Nun hab ich mir grad fein angewöhnt, Programmabstürze mit Exceptions abzufangen... und schon hab ich Probleme beim Weiterentwickeln
Hi droptix!

http://www.python-forum.de/post-8616.html#8616

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
pr0stAta
User
Beiträge: 271
Registriert: Freitag 17. September 2004, 11:49
Wohnort: Bremen

Oder um Leonidas Beispiel aufzugreifen:

Code: Alles auswählen

try:
    foo()
except IOError, error_code:
    print 'IOError was found, ErrorCode: ', error_code
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Mit "IOError" fängt man ja nur IO-Fehler ab :) Ich würde ja gern alle Fehler abfangen. Sonst vergisst man vielleicht eine Exception und man hat wieder nen Programmabsturz.

Ich werde mir mal das hier anschauen:

Code: Alles auswählen

try:
    foo()
except Exception, errorCode:
    print errorCode
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Das ist schonmal ein Schritt in die richtige Richtung, aber der 'errorCode' bringt mir nur die letzte Zeile der sonst so ausführlichen Fehlerbeschreibung. Ich erhalte den Exception-Name, aber z.B. keine Zeilennummer mehr.

Kriegt man das noch mit hin?

Ist doch sonst sehr bescheiden, wenn man Fehler sucht... wie handhabt ihr das denn?
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Schau dir nochmal das an, was Gerold gepostet hat. :wink:
mfg

Thomas :-)
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Versuch das grad zu verstehen... traceback ist Neuland :D Sieht schonmal sehr interessant aus.

Vielleicht noch eine kleine Hilfe von euch? Es wäre nett, wenn ich in meinem Programm eine Variable 'debug = True' setzen könnte. Wenn die 'True' ist, dann soll die volle Fehlermeldung kommen. Wenn nicht, dann bleibt das Programm stumm. Ich dachte an sowas hier:

Code: Alles auswählen

import sys, traceback

class foo:
    def __init__(self):
        self.debug = True
        # cause exception by calling non-exisiting method
        try:
            self.bar2()
        except Exception, errorCode:
            print "Something went wrong!"
            self.error(traceback.tralala("i.dont.know"))
    
    def bar(self):
        print "bar was called"
    
    def error(self, error):
        if self.debug == True:
            print "Full error message only if 'debug=True' :)"
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

OK, hier die Lösung! Vielen Dank für den wertvollen Tipp!

Code: Alles auswählen

import sys, traceback

class foo:
    def __init__(self):
        self.debug = True
        # cause exception by calling non-exisiting method
        try:
            self.bar2()
        except:
            print "Something went wrong!"
            self.error()
   
    def bar(self):
        print "bar was called"
   
    def error(self):
        if self.debug == True:
            traceback.print_tb(sys.exc_traceback)

if __name__ == "__main__":
    foo()
Zuletzt geändert von droptix am Dienstag 23. Mai 2006, 13:58, insgesamt 1-mal geändert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

droptix hat geschrieben:Es wäre nett, wenn ich in meinem Programm eine Variable 'debug = True' setzen könnte. Wenn die 'True' ist, dann soll die volle Fehlermeldung kommen.
Hi droptix!

Die Variable "__debug__" zeigt auf, ob sich Python im Debug-Modus befindet oder nicht. Leider ist diese Variable unbrauchbar, da sich Python ständig im Debug-Modus befindet. Nur der Aufruf "python -O" oder "python -OO" setzt die Variable "__debug__" auf False.

Deshalb empfehle ich eine Lösung mit "optparse". Hier ein Beispiel:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from optparse import OptionParser

#----------------------------------------------------------------------
def parse_options():
    """
    Wertet die Argumente aus und gibt diese zurück
    """

    #Usage-Text angeben und Parser-Objekt erzeugen
    usage = "%prog [options]\n\n" + \
            "    Kurze Erklaerung zum Programm\n" + \
            "    by Gerold Penz 2006 -- gerold.penz@tirol.utanet.at"
    parser = OptionParser(usage = usage)

    #Optionen hinzufuegen
    parser.add_option("-d", "--debug",
        dest = "debug",
        action = "store_true",
        default = False,
        help = "show debug messages")

    #Optionen parsen
    (options, args) = parser.parse_args()

    # DEBUG als globale Variable setzen
    global DEBUG
    DEBUG = options.debug

    #Rueckgabe
    return (options, args)

#----------------------------------------------------------------------
def main():
    """
    Hauptprozedur
    """
    
    #Optionen und Argumente parsen
    (options, args) = parse_options()
    
    # Ab hier kann gearbeitet werden.
    # ...
    # ...
    if DEBUG:
        print "Ich bin im Debug-Modus!"
    
#----------------------------------------------------------------------
if __name__ == "__main__":
    main()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Was spricht gegen

Code: Alles auswählen

except:
  print "Das geht hier alles nicht! So ein Mist!"
  raise
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Einiges :wink:

Also wie ich schon ganz oben beschrieben hatte (einfach mal Code kopieren und ausführen), ist es zwar schön, dass die Exception den Programmabsturz abfängt... Aber eine 'äußere' Exception greift immer dann, wenn keine weitere im Inneren des Programm-Codes kommt... das muss ich dir ja bestimmt nicht erklären... bist schließlich schon länger hier als ich :lol:

Für mein eigenes Debugging will ich im Inneren nun aber nicht tausend weitere Exceptions setzen, um den Fehler einzugrenzen. Während ich entwickle, soll die Fehlermeldung schon kommen. Und ich will dann einfach eine Variable auf 'False' setzen, wenn ich das Programm veröffentliche und dem Anwender vorsetze, um die Fehlermeldungen mit einer lesbaren Meldung abzufangen.

Das 'traceback' im Zusammenhang mit einer eigenen debug-Funktion/Methode erfüllt nun genau den Zweck den ich brauche *freu*
Antworten