SAMOUCZEK JĘZYKA PYTHON ROZDZIAŁY   
Rozdział 7: Błędy i wyjątki

1: Błędy składni - 2: Wyjątki - 3: Obsługa wyjątków - 4: Zgłaszanie wyjątków
5: Wyjątki definiowane przez użytkownika - 6: Jak posprzątać po bałaganiarzu?

Lekcja 3: Obsługa wyjątków


Możliwe jest napisanie programu, który obsługuje wybrane wyjątki. W poniższym przykładzie użytkownik podaje dane na wejściu aż do momentu, kiedy zostanie wprowadzona poprawna liczba całkowita. Użytkownik może przerwać pracę (poprzez naciśnięcie Control-C lub dowolny sposobem, jaki jest możliwy poprzez klawiaturę w danym systemie operacyjnym). Przerwanie użytkownika sygnalizowane jest poprzez zgłoszenie wyjątku KeyboardInterrupt.

>>> while 1:
...     try:
...         x = int(raw_input("Prosze wprowadzic liczbe: "))
...         break
...     except ValueError:
...         print "Uch! to nie jest poprawna liczba! 
Sprobuj jeszcze raz..." ... Prosze wprowadzic liczbe:

Jak działa instrukcja try:

  • Na początku wykonywana jest klauzula try (czyli instrukcje pomiędzy try a except).
  • Jeżeli nie pojawi się żaden wyjątek klauzula except jest pomijana. Wykonanie instrukcji try uważa się za zakończone. Jeżeli podczas wykonywania klauzuli try pojawi się wyjątek, reszta niewykonanych instrukcji jest pomijana. Następnie, w zależności od tego, czy jego typ pasuje do typów wyjątków wymienionych w części except, wykonywany jest kod następujący w tym bloku, a potem interpreter przechodzi do wykonywania instrukcji umieszczonych po całym bloku try...except.
  • W przypadku pojawienia się wyjątku, który nie zostanie dopasowany do żadnego z wyjątków wymienionych w klauzuli except, zostaje on przekazany do do następnych, zewnętrznych instrukcji try. Jeżeli również tam nie zostanie znaleziony odpowiadający mu blok except, wyjątek ten nie zostanie wyłapany, stanie nieobsłużonym wyjątkiem, a wykonywanie programu zostanie wstrzymane wraz z pojawieniem się komunikatu podobnego do pokazanego powyżej.
Aby umożliwić obsługę wielu wyjątków, instrukcja try może posiadać więcej niż jedną klauzulę except. W takim przypadku, kod dla co najwyżej jednego wyjątku zostanie wykonany. Kody obsługi wyjątków wykonywane są tylko dla wyjątków, które zostały zgłoszone w odpowiadającej im części try, a nie w innych, sąsiednich częściach except. Klauzula except może zawierać nazwy wielu wyjątków, podanych w formie listy otoczonej nawiasami okrągłymi (czyli w formie krotki):

... except (RuntimeError, TypeError, NameError):
...     pass

W ostatniej podanej klauzuli except można pominąć nazwę lub nazwy wyjątków w celu obsłużenia dowolnego wyjątku. Należy posługiwać się tą konstrukcją bardzo ostrożnie, ponieważ jest to sposób do łatwego zamaskowania prawdziwego wystąpienia błędu w programie! Można jej również użyć do wydrukowania komunikatu o błędzie i ponownie zgłosić wyłapany wyjątek (umożliwiając w ten sposób funkcji wywołującej wyłapanie zgłoszonego wyjątku):

import string, sys

try:
    f = open('mojplik.txt')
    s = f.readline()
    i = int(string.strip(s))
except IOError, (errno, strerror):
    print "Blad I/O (%s): %s" % (errno, strerror)
except ValueError:
    print "Nie moge przeksztalcic danej w liczbe calkowita."
except:
    print "Nieobslugiwany blad:", sys.exc_info()[0]
    raise

Instrukcja try ... except wyposażona jest w opcjonalną klauzulę else, która musi pojawić się za wszystkimi podanymi blokami except. Można po niej umieścić kod, który zostanie wykonany, jeżeli nie zostanie zgłoszony wyjątek:

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print 'nie moge otworzyc  pliku', arg
    else:
        print arg, 'ma', len(f.readlines()), 'linie/linii'
        f.close()

Wyjątek może pojawić się z przypisaną sobie wartością, która nazywana jest argumentem wyjątku. Obecność tej wartości i jej typ zależy od rodzaju wyjątku. Jeżeli chce się poznać tę wartość, należy podać nazwę zmiennej (lub listę zamiennych) za nazwą typu wyjątku w klauzuli except:
>>> try:
...     szynka()
... except NameError, x:
...     print 'nazwa', x, 'nie została zdefiniowana'
...
nazwa szynka nie została zdefiniowana
Argument ten (jeśli istnieje) pokazywany jest w ostatniej części («detail») komunikatu o niewyłapanym wyjątku. Kody obsługujące wyjątek uruchamiane są nie tylko po zgłoszeniu wyjątku w ich klauzuli try, ale także w przypadku, gdy pojawią się one w instrukcjach try umieszczonych w wywoływanych funkcjach (nawet pośrednio):
>>> def to_sie_nie_uda():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError, detale:
...     print 'Obsługa błędu wykonania programu:', detale
...
Obsługa błędu wykonania programu: integer division or modulo
Strona główna - O Pythonie - Interpreter - Samouczek - Przykłady programów - Linki