Python · wyjątki

Wyjątki w Pythonie — ćwiczenia z obsługi błędnych danych

try, except, raise i finally na błędnych danych. Trzy funkcje z wartością zastępczą, rozwiązania i typowe pomyłki.

45 minutPoziom podstawowyPliki i rozwiązania

Materiał redakcyjny TablicaPro · liceum i technikum

try:
    int("abc")
except ValueError:
    print("To nie jest liczba")
› To nie jest liczba
Program nie zatrzymuje się.

Programy dostają czasem dane, których autor się nie spodziewał: tekst zamiast liczby, zero w mianowniku, brakujący element. Zamiast kończyć się komunikatem o błędzie, dobrze napisany program potrafi na to zareagować. Na lekcji uczniowie obsługują trzy rodzaje takich sytuacji instrukcją try ... except.

Scenariusz jest przeznaczony na 45 minut dla klasy znającej funkcje i konwersję typów — na przykład po lekcjach o funkcjach i typach danych.

Przygotowanie stanowisk

Potrzebny jest Python 3 i edytor lub IDLE. Rozpakuj pakiet z sekcji materiałów do osobnego folderu i uruchamiaj skrypty z tego folderu. Program uruchomisz przez Run → Run Module albo poleceniem python start.py, python3 start.py lub py start.py.

Cele i plan lekcji

Po zajęciach uczeń potrafi:

  • przeczytać komunikat błędu i nazwać typ wyjątku (ValueError, ZeroDivisionError, IndexError);
  • obsłużyć wyjątek blokiem try ... except i zwrócić wartość zastępczą;
  • zgłosić własny błąd instrukcją raise i użyć finally;
  • wyjaśnić, że przechwytywać należy konkretne wyjątki, a nie wszystkie.
CzasPraca na lekcji
0–5 minProblem: program zatrzymuje się na int("abc")
5–15 mintry i except, nazwa wyjątku
15–22 minraise, finally, wartość zastępcza
22–37 minTrzy zadania samodzielne
37–42 minOmówienie wyników
42–45 minPytania kontrolne

try, except, raise, finally

Blok try zawiera kod, który może zgłosić błąd. Jeśli się to stanie, wykonanie przechodzi do pasującego bloku except, a program działa dalej. Najlepiej podawać konkretny typ wyjątku, np. except ValueError, bo „goły” except ukrywa także błędy programisty (literówki w nazwach).

Najczęstsze wyjątki w lekcji: ValueError (np. int("abc")), ZeroDivisionError (dzielenie przez zero), IndexError (indeks poza listą), TypeError (zły typ danych). Własny błąd zgłaszamy instrukcją raise ValueError("opis"), a opis odczytamy przez except ValueError as blad. Blok finally wykonuje się zawsze, niezależnie od tego, czy błąd wystąpił — używa się go do porządków, np. zamknięcia pliku.

Zadania

Zadanie 1. Bezpieczna liczba. Napisz funkcję wczytaj_liczbe(tekst), która zwraca liczbę całkowitą albo None, gdy tekst nie jest liczbą. Sprawdź "12", "-7", "abc", "3.5" i pusty napis.

Zadanie 2. Dzielenie. Napisz funkcję podziel(a, b), która zamiast zgłaszać błąd dla b = 0 zwraca napis "dzielenie przez zero". Sprawdź podziel(10, 4) i podziel(5, 0).

Zadanie 3. Średnia z tekstów. Napisz funkcję srednia_z_tekstow(lista), która pomija niepoprawne elementy, zlicza je i zwraca średnią z dwoma miejscami oraz liczbę błędów. Gdy nie ma poprawnych liczb, ma zgłosić ValueError. Sprawdź listy ["8", "x", "10", "4"] i ["a", "b"] (z blokiem finally).

Dla chętnych: napisz funkcję zwracającą element listy o podanym indeksie albo None, gdy indeks jest poza zakresem.

Rozwiązanie i wyniki

def wczytaj_liczbe(tekst):
    try:
        return int(tekst)
    except ValueError:
        return None


def podziel(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return "dzielenie przez zero"


def srednia_z_tekstow(lista):
    liczby = []
    bledy = 0
    for t in lista:
        n = wczytaj_liczbe(t)
        if n is None:
            bledy = bledy + 1
        else:
            liczby.append(n)
    if len(liczby) == 0:
        raise ValueError("brak poprawnych liczb")
    return round(sum(liczby) / len(liczby), 2), bledy


# Zadanie 1
for t in ["12", "-7", "abc", "3.5", ""]:
    print(repr(t), wczytaj_liczbe(t))

# Zadanie 2
print(podziel(10, 4), podziel(5, 0))

# Zadanie 3
print(srednia_z_tekstow(["8", "x", "10", "4"]))
try:
    srednia_z_tekstow(["a", "b"])
except ValueError as blad:
    print("Blad:", blad)
finally:
    print("Koniec obliczen")

Program wypisze:

'12' 12
'-7' -7
'abc' None
'3.5' None
'' None
2.5 dzielenie przez zero
(7.33, 1)
Blad: brak poprawnych liczb
Koniec obliczen

Zauważ, że "3.5" i pusty napis dają None — int nie czyta ułamków zapisanych tekstem. Średnia z 8, 10 i 4 to 22/3, czyli 7.33, a jeden element ("x") został pominięty. Zadanie dla chętnych (rozszerzenie.py) wypisuje:

2 None

Typowe błędy

ObjawCo sprawdzić
Program nadal kończy się błędemBlok except ma inny typ wyjątku niż zgłoszony.
Błąd literówki „znika”Użyto gołego except:, który przechwytuje wszystko, także własne pomyłki.
Funkcja zwraca None, a oczekiwano liczbyWartość zastępcza została zwrócona, ale wynik użyto bez sprawdzenia is None.
int("3.5") daje NoneTo ValueError; przekonwertuj przez float, jeśli ułamki są dopuszczalne.
Komunikat z raise nie pojawia sięBrak as blad albo nie wypisano zmiennej.
finally wypisuje się też bez błęduTo zamierzone zachowanie — finally wykonuje się zawsze.

Pytania kontrolne i punktacja

  1. Który wyjątek zgłosi 10 / 0?
  2. Kiedy wykona się blok finally?
  3. Dlaczego lepiej pisać except ValueError niż samo except?

Odpowiedzi: ZeroDivisionError. Zawsze — po poprawnym wykonaniu bloku try i po obsłużonym lub nieobsłużonym błędzie. Bo konkretny wyjątek nie ukrywa innych, nieoczekiwanych błędów.

Proponowana punktacja (razem 10 punktów): zadanie 1 — try/except 2 pkt, pięć wyników 1 pkt; zadanie 2 — obsługa zera 2 pkt, dwa wyniki 1 pkt; zadanie 3 — pomijanie błędów i licznik 2 pkt, raise 1 pkt, finally i test 1 pkt. Zadanie dla chętnych nie jest wymagane do pełnej oceny.

Materiały do pobrania

Rozpakuj ZIP przed otwarciem plików. Materiały są dostępne bez logowania; publiczne rozwiązanie służy nauce i samodzielnemu sprawdzeniu, a nie poufnemu sprawdzianowi.

Co dalej?

Następny krok to testowanie funkcji instrukcją assert i praca z plikami, w których błędy zdarzają się najczęściej. Ten materiał rozwija dział o obsłudze błędów w kursie Python w TablicaPro, gdzie znajdziesz prezentacje, ćwiczenia i testy do prowadzenia lekcji.

Źródła techniczne: błędy i wyjątki w oficjalnym tutorialu. Zobacz też lekcję o plikach tekstowych.

Poprowadź kolejne lekcje Python

Pełny kurs: prezentacje, ćwiczenia i testy do pracy z klasą.

Kup dostęp do kursu Python →

Zobacz program kursu