Seite 1 von 1

[gelöst] Ausnahmebehandlung per Funktion

Verfasst: Donnerstag 8. Januar 2009, 20:20
von snafu
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?

Verfasst: Donnerstag 8. Januar 2009, 20:43
von str1442
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.

Verfasst: Donnerstag 8. Januar 2009, 20:55
von snafu
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)

Verfasst: Donnerstag 8. Januar 2009, 21:00
von str1442
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.

Verfasst: Donnerstag 8. Januar 2009, 21:23
von snafu
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)