Vererbungslehre

Fehlerbehandlung und objektorientierte Programmierung in Python

01.11.2006
Mit Skriptsprache Python entfaltet erst dann ihre ganze Kraft, wenn objektorientierte Konzepte zum Einsatz kommen. Sie hilft Ihnen, komplexe Probleme in überschaubre Einheiten zu zerlegen.

Im ersten Teil des Python-Kurses (09/2006, S. 80) haben Sie den interaktiven Interpreter, Datentypen und Ablaufstrukturen kennengelernt. Wie Sie im zweiten Teil (10/2006, S. 68) gesehen haben, macht Python das Aufteilen von Code in Funktionen, Module und Pakete ganz einfach. Dieser dritte Teil zeigt, wie Python Fehler behandelt und bietet einen Einstieg in die objektorientierte Programmierung.

Ausnahmebehandlung

Haben Sie schon ein Programm zum Bearbeiten von Dateien geschrieben, ist Ihnen möglicherweise aufgefallen, dass Python Fehler beim Öffenen einer Datei nicht besonders freundlich handhabt: Fehlt zum Beispiel das entsprechende File, bricht das Programm beim Aufruf datei = open("nicht_da.txt") mit der folgenden Fehlerausgabe ab:

Traceback (most recent call last↩
):
  File "./nicht_da.py", line 4, ↩
in ?
    datei = open("nicht_da.txt")
IOError: [Errno 2] No such file ↩
or directory: 'nicht_da.txt'

Bei der Ausgabe handelt es sich um einen sogenannten Traceback, der zeigt, wo der Fehler auftrat und welche Funktionen beteiligt waren, bevor der Fehler auftrat. Im Beispiel gibt es nur eine Zeile direkt auf Modulebene, deshalb ist von der Aufrufreihenfolge nicht viel zu sehen. Python kennt nun Möglichkeiten zum Abfangen des Fehlers:

try:
    datei = open("nicht_da.txt")
except IOError:
    print "Fehler beim Öffnen de↩
r Datei"
    print "Und weiter nach dem F↩
ehler …"

Dabei ist IOError der Typ der Ausnahme, wie er aus dem Traceback erkennbar ist. Allerdings nutzen die zwei Zeilen bei der Fehlersuche wenig, weil die Angabe der problematischen Datei in der Ausgabe fehlt. Den Dateinamen bekommen Sie durch eine kleine Änderung am Code:

try:
    datei = open("nicht_da.txt")
except IOError, io_exception:
    print 'Fehler beim Öffnen de↩
r Datei "%s"' % io_exception.fil↩
ename
    print "Und weiter nach dem F↩
ehler …"

Das durch io_exception bezeichnete Objekt ist ein Ausnahme-Objekt, hier vom Typ IOError. IOError-Objekte haben unter anderem ein Attribut filename, das die problematische Datei bezeichnet.

Nach dem Ändern lautet die Ausgabe des obigen Codes:

Fehler beim Öffnen der Datei "ni↩
cht_da.txt"
Und weiter nach dem Fehler …

Wie Sie sehen, erscheint zwar der Fehlertext, das Programm geht aber über den Fehler hinweg. Beachten Sie, dass Sie eine Ausnahme nicht direkt beim fehlererzeugenden Code abfangen müssen (Listing 1).

Listing 1

import sys
def log_datei(datei_name):
    return open(datei_name, 'w')
def start():
    # "global" sparsam verwenden
    global log
    log = log_datei("prog.log")
    print "Programm gestartet"
def main():
    try:
        start()
    except IOError, exc:
        print exc
        sys.exit()
if __name__ == '__main__':
    main()

Existiert die Datei prog.log Datei nicht oder verweigert das Betriebssystem den Zugriff, pflanzt sich der Fehler so lange fort, bis das Try/Except-Konstrukt in der Funktion main ihn abgefängt. Falls keine Fehlerbehandlung für einen bestimmten Ausnahmetyp vohanden ist, beendet sich das Programm mit einem Traceback. Unvorhergesehene Fehler fallen also immer auf.

Mehrere Ausnahmetypen

Wollen Sie mehrere mögliche Ausnahmen behandeln, bietet es sich an, diese mit verschiedenen except-Zweigen abzufangen (Listing 2). Ist die Behandlung für beide Fehlerarten gleich, sollten Sie Redundanz vermeiden, indem Sie beide except-Zweige zusammenfassen.

Listing 2

try:
    tu_was()
except IOError, io_exception:
    # verwende io_exception, um
    # den Fehler zu behandeln
    …
except OSError, os_exception:
    # verwende os_exception, um
    # den Fehler zu behandeln
    …
try:
    tu_was()
except (IOError, OSError):
    …

Beim Konstrukt im Listing 3 sind die Klammern zwingend notwendig. Fehlen sie, versteht Python unter IOError, OSError ein Ausnahme-Objekt vom Typ IOError namens OSError, analog zum Beispiel IOError, io_exception weiter oben. Auch hier ist zusätzlich die Angabe eines Namens für ein Ausnahmeobjekt möglich, das Ihnen dann weitere Informationen bereitstellt.

try:
    tu_was()
except (IOError, OSError), excep↩
tion:
    …

Das hat jedoch den Nachteil, dass exception je nach aufgetretenem Fehler einen unterschiedlichen Typ und damit verschiedene Attribute hat. Um sich Fallunterscheidungen zu ersparen, sollten Sie getrennte except-Zweige nehmen. Wollen Sie alle Ausnahmen – egal welche – abfangen, verwenden Sie except ohne Ausnahmetypen:

try:
    tu_was()
except:
    …

Diese Möglichkeit spart auf den ersten Blick Schreibarbeit. Sie hat aber ihre Tücken: Damit fallen alle Ausnahmen unter den Tisch, unter anderem KeyboardInterrupt (Drücken von [Strg]+[C]) und SyntaxError (zum Beispiel beim Importieren eines fehlerhaften Moduls). Daher sollten Sie die obige Variante nur auf der obersten Ebene einer Software verwenden, um beispielsweise Traceback-Ausgaben in einem Produktionssystem zu verhindern.

Fangen Sie in einer Try/Except-Anweisung mehrere spezifische Fehler parallel zu einer allgemeinen except-Zeile ab, kommt es auf die richtige Reihenfolge an: Die Zeilen mit den speziellen Exceptions stehen vor dem allgemeinen except (Listing 3). Alle Try/Except-Konstrukte erlauben einen else-Zweig, der zum Zuge kommt, wenn keine Ausnahme ausgelöst auftrat (Listing 4).

Listing 3

try:
    tu_was()
except IOError:
    …
except OSError:
    …
except:
    …

Listing 4

try:
    datei = open("test.txt")
except IOError:
    print "I/O-Fehler"
else:
    print "alles ok"

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

  • Einfache Architektur
    Spezialmethoden und geschicktes Vererben von Klassenmethoden vereinfachen das Programmieren mit Python drastisch. Unser Workshop zeigt, welche Tricks die Skriptsprache auf Lager hat.
  • Typische Fehler in Python-Code vermeiden
    Python ist einfach – aber nicht so einfach, dass man es allein durch Lesen von Code lernen könnte. Mit etwas Hintergrundwissen vermeiden Sie typische Fehler in Python-Code und schreiben so bessere Programme.
  • 3D-Welten mit Python und Panda3D
    Es gibt zwar einige freie Spiele-Engines, doch nicht jede ist leicht zu programmieren. Panda3D vereinfacht durch die Skriptsprache Python den Einstieg, bietet aber auch Potenzial für Profis.
  • Bildverarbeitung mit den Skriptsprachen Perl und Python
    Mit nur wenigen Zahlen Code korrigieren Sie das Format digitaler Bilder, passen die Metadaten an oder beschriften die Fotos für den Upload in ein Online-Album.
  • Entwicklungshelfer
    Nachdem in den ersten Teilen der Python-Einführung die Sprache beschrieben wurde, geht es im letzten Teil um nützliche Hilfen rund um Python.
Kommentare

Infos zur Publikation

title_2014_09

Digitale Ausgabe: Preis € 4,95
(inkl. 19% MwSt.)

Mit der Zeitschrift LinuxUser sind Sie als Power-User, Shell-Guru oder Administrator im kleinen Unternehmen monatlich auf dem aktuelle Stand in Sachen Linux und Open Source.

Sie sind sich nicht sicher, ob die Themen Ihnen liegen? Im Probeabo erhalten Sie drei Ausgaben zum reduzierten Preis. Einzelhefte, Abonnements sowie digitale Ausgaben erwerben Sie ganz einfach in unserem Online-Shop.

NEU: DIGITALE AUSGABEN FÜR TABLET & SMARTPHONE

HINWEIS ZU PAYPAL: Die Zahlung ist auch ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!       

Tipp der Woche

Schnell Multi-Boot-Medien mit MultiCD erstellen
Schnell Multi-Boot-Medien mit MultiCD erstellen
Tim Schürmann, 24.06.2014 12:40, 0 Kommentare

Wer mehrere nützliche Live-Systeme auf eine DVD brennen möchte, kommt mit den Startmedienerstellern der Distributionen nicht besonders weit: Diese ...

Aktuelle Fragen

Windows 8 startet nur mit externer Festplatte
Anne La, 10.09.2014 17:25, 4 Antworten
Hallo Leute, also, ich bin auf folgendes Problem gestoßen: Ich habe Ubuntu 14.04 auf meiner...
Videoüberwachung mit Zoneminder
Heinz Becker, 10.08.2014 17:57, 0 Antworten
Hallo, ich habe den ZONEMINDER erfolgreich installiert. Das Bild erscheint jedoch nicht,...
internes Wlan und USB-Wlan-Srick
Gerhard Blobner, 04.08.2014 15:20, 2 Antworten
Hallo Linux-Forum: ich bin ein neuer Linux-User (ca. 25 Jahre Windows) und bin von WIN 8 auf Mint...
Server antwortet mit falschem Namen
oin notna, 21.07.2014 19:13, 1 Antworten
Hallo liebe Community, Ich habe mit Apache einen Server aufgesetzt. Soweit, so gut. Im Heimnet...
o2 surfstick software für ubuntu?
daniel soltek, 15.07.2014 18:27, 1 Antworten
hallo zusammen, habe mir einen o2 surfstick huawei bestellt und gerade festgestellt, das der nic...