Seite 1 von 1

Exception abschalten

Verfasst: Montag 22. Mai 2006, 13:09
von droptix
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?

Re: Exception abschalten

Verfasst: Montag 22. Mai 2006, 14:02
von Leonidas
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.

Re: Exception abschalten

Verfasst: Montag 22. Mai 2006, 14:35
von gerold
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
:-)

Verfasst: Montag 22. Mai 2006, 14:49
von pr0stAta
Oder um Leonidas Beispiel aufzugreifen:

Code: Alles auswählen

try:
    foo()
except IOError, error_code:
    print 'IOError was found, ErrorCode: ', error_code

IOError

Verfasst: Montag 22. Mai 2006, 16:39
von droptix
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

Nur die letzte Zeile

Verfasst: Montag 22. Mai 2006, 19:27
von droptix
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?

Verfasst: Montag 22. Mai 2006, 19:31
von Python 47
Schau dir nochmal das an, was Gerold gepostet hat. :wink:

traceback

Verfasst: Montag 22. Mai 2006, 19:58
von droptix
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' :)"

Lösung

Verfasst: Montag 22. Mai 2006, 20:07
von droptix
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()

Re: traceback

Verfasst: Montag 22. Mai 2006, 20:31
von gerold
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
:-)

Verfasst: Dienstag 23. Mai 2006, 10:46
von Joghurt
Was spricht gegen

Code: Alles auswählen

except:
  print "Das geht hier alles nicht! So ein Mist!"
  raise

Einiges

Verfasst: Dienstag 23. Mai 2006, 13:56
von droptix
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*