[gelöst] Ausnahmebehandlung per Funktion

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
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hallo!

Ich behandle in einem Skript 4 Ausnahmen:

Code: Alles auswählen

def main():
    "Use first argument from command-line as name for module to locate."
    try:
        module = sys.argv[1]
    except IndexError:
        print >> sys.stderr, 'Usage: %s module' % sys.argv[0]
        exit(1) 
    try:
        print locate(module)
    except BuiltinException, why:
        print >> sys.stderr, why
        exit(2)
    except ImportError, why:
        print >> sys.stderr, why
        exit(3)
    except ValueError, why:
        print >> sys.stderr, why
        exit(4)
Zumindest Exitcode 2-4 (vielleicht auch den ersten?) kann mir hier wohl getreu dem Motto "don't repeat yourself" als Funktion schreiben. Dachte ich zumindest. So sieht sie bisher aus:

Code: Alles auswählen

def handle_exceptions(cmd, *excs):
    i = 1
    for exc in excs:
        try:
            cmd
        except exc, why:
            print >> sys.stderr, why
            exit(i)
Dies ist natürlich nur ein Ansatz, den ich auch noch nicht getestet habe, da er IMHO nicht wunschgemäß funktionieren wird. Wie also kann ich weitere except-Blöcke einfügen ohne jedes Mal einen neuen try-Block starten zu müssen?
Zuletzt geändert von snafu am Donnerstag 8. Januar 2009, 21:24, insgesamt 1-mal geändert.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Du kannst mehrere Exceptions in einem Tupel abfangen, achte nur auf die Syntax:

Code: Alles auswählen

# Wrong
try:
 ...
except Exc1, Exc2, why:

# Right

try:
 ...
except (Exc1, Exc2), why:
In Python 3.0 wird das übringens mit (Exc1, Exc2, ...) as why gehändelt. Man kann übringens auch Superklassen von Exceptions abfangen und fängt automatisch alle Subklassen mit.
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das hatte ich gerade schon beim Lesen in der Doku gesehen (abfangen von mehreren Exceptions in einem Schritt). Allerdings spuckt mein Skript ja unterschiedliche Exitcodes je nach Exception aus. Komme ich auch irgendwie an den Typ der zuletzt geworfenen Exception? Am liebsten wäre mir ein Tupel (exc_type, msg).

Ich habe schon sys.exc_info() probiert, was aber scheinbar nicht funktioniert (Python 2.6).

Code: Alles auswählen

>>> try:
...     print bla
... except (NameError, IndexError) as exc:
...     print exc
... 
name 'bla' is not defined
>>> import sys
>>> sys.exc_info()
(None, None, None)
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Business as usual und so:

Code: Alles auswählen

In [1]: import sys

In [2]: try:
   ...:     raise ValueError("Message")
   ...: except ValueError, e:
   ...:     print sys.exc_info()
   ...:     print e.message, e.__class__, e.__class__.__name__
   ...:     
   ...:     
(<type 'exceptions.ValueError'>, ValueError('Message',), <traceback object at 0x9b0fcfc>)
Message <type 'exceptions.ValueError'> ValueError
Das Traceback Objekt sollte man nach Info der Doku übringens nicht fangen wenn man es nicht braucht.
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, kam mir dann auch in den Sinn. ;) (Also daß die Infos nur im Except-Block abfragbar sind, wie's ja eigentlich auch in der Doku beschrieben wird, sofern man genau liest *hust*)

Ich hab's jetzt so gelöst: http://paste.pocoo.org/show/98643/

Danke für die Hilfe. :)

EDIT: Abfrage nun über sys.exc_type.__name__ und somit kein Import der Exceptions mehr. (err_code-Schlüssel sind jetzt natürlich Strings)
Antworten