Jak czytać czerwony komunikat i skąd wiadomo, co się stało
try i except: program nie przerywa się na byle czym
Pętla „pytaj, aż podasz liczbę”
Rozgrzewka · 3 minuty
Co pamiętacie z lekcji 15?
Co robi zapis with open("notes.txt", encoding="utf-8") as f:?
Czym różnią się tryby "r", "w" i "a" w funkcji open?
Jak policzyć, ile linii ma otwarty plik?
Część 1 · Rodzaje błędów
Trzy sposoby, na jakie program może zawieść
Błąd wykonania nazywamy wyjątkiem: sytuacją, której program nie umie wykonać, choć zapisany jest poprawnie. Średnia z 2 i 8 to (2 + 8) / 2, czyli 5.0. Bez nawiasu Python liczy 2 + 8 / 2 i daje 6.0, bez żadnego ostrzeżenia.
docs.python.org, The Python Tutorial, rozdz. 8.1 (Syntax Errors) i 8.2 (Exceptions) · Podręcznik Informatyka na czasie 2 (Nowa Era), s. 97 (błąd składniowy, rys. 6.5) i s. 98 (ramka „Warto wiedzieć”, błąd logiczny)
Część 1 · Komunikat o błędzie
Czerwony napis czyta się od dołu
Traceback (most recent call last):
File ".../age.py", line 2, in <module>
age = int(input())
^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'szesnascie'
1. linia zapowiada: dalej jest ślad błędu.
2. linia to plik i numer linii, w której program się zatrzymał.
3. i 4. pokazują tę linię kodu i strzałkami miejsce błędu.
Ostatnia linia jest najważniejsza: ValueError to typ wyjątku, a po dwukropku opis po angielsku.
W praktyce: strzałki pokazują miejsce, w którym interpreter wykrył błąd, a nie zawsze to, które trzeba poprawić. Przy brakującym dwukropku po while True strzałki wskazują dopiero na print w następnej części linii.
docs.python.org, The Python Tutorial, rozdz. 8.2 (Exceptions)
Część 2 · try i except
Dwie drogi zamiast czerwonego napisu
Zapis try („spróbuj”) mówi: wykonaj te instrukcje, a jeśli poleci wyjątek wymieniony po except („w razie”), zrób zamiast tego blok ratunkowy. Program nie przerywa się, tylko leci dalej.
docs.python.org, The Python Tutorial, rozdz. 8.3 (Handling Exceptions)
Część 2 · Kilka except
Jeden try, osobna odpowiedź na każdy wyjątek
print("Podaj dzielną:")
try:
a = int(input())
print("Podaj dzielnik:")
b = int(input())
print("Wynik:", a / b)
except ValueError:
print("To nie jest liczba całkowita.")
except ZeroDivisionError:
print("Przez zero nie dzielimy.")
Wpisano
Na ekranie
10 i 4
Wynik: 2.5
10 i 0
Przez zero nie dzielimy.
10 i „dwa”
To nie jest liczba całkowita.
Python sprawdza bloki except po kolei i wykonuje pierwszy pasujący. W żadnym z trzech przypadków program się nie przerywa.
docs.python.org, The Python Tutorial, rozdz. 8.3 (Handling Exceptions)
Część 2 · Pytaj aż do skutku
Pętla, która nie odpuszcza
while True:
print("Podaj swój wiek:")
try:
age = int(input())
break
except ValueError:
print("To nie jest liczba. Spróbuj jeszcze raz.")
print("Za rok będziesz mieć", age + 1)
Podaj swój wiek:
szesnascie
To nie jest liczba. Spróbuj jeszcze raz.
Podaj swój wiek:
16.5
To nie jest liczba. Spróbuj jeszcze raz.
Podaj swój wiek:
16
Za rok będziesz mieć 17
Zapis 16.5 też daje ValueError: funkcja int przyjmuje wyłącznie liczby całkowite.
W praktyce: przerwanie programu klawiszami Ctrl i C to również wyjątek, o nazwie KeyboardInterrupt. Dzięki temu program z pętlą „pytaj aż do skutku” da się zamknąć, nawet gdy nikt nie wpisze poprawnej liczby.
docs.python.org, The Python Tutorial, rozdz. 8.3 (Handling Exceptions)
Ćwiczenie · przy komputerze · 12 minut
Ćwiczenie: program, który się nie wywala
Załóż plik divide.py. Program pyta o dwie liczby całkowite i wypisuje ich iloraz. Dodaj osobny except dla ValueError i osobny dla ZeroDivisionError. Sprawdź na parach: 10 i 4, 10 i 0, 10 i „dwa”.
Przerób divide.py tak, żeby pytał o dzielnik w pętli while True, aż dostanie liczbę, przez którą da się podzielić. Gdzie musi stać break?
Nowy plik count.py: program otwiera notes.txt, wypisuje liczbę linii, a gdy pliku nie ma, pisze „Nie ma takiego pliku.” zamiast czerwonego komunikatu. Uruchom najpierw bez pliku, potem z plikiem o trzech liniach.
Jak to sprawdzić
Program jest gotowy dopiero wtedy, gdy przy żadnym z podanych wejść nie widzicie słowa Traceback. Jeśli je widzicie, przeczytajcie ostatnią linię komunikatu: nazwa typu przed dwukropkiem to dokładnie to, co brakuje po except.
Sprawdzenie
Trzy pytania na koniec
Czym różni się błąd składni od wyjątku?
Która linia komunikatu o błędzie mówi, co się stało, i czego z niej używamy w except?
Program ma pytać o liczbę, aż użytkownik poda poprawną. Czego potrzeba oprócz try i except?
Podsumowanie
A jak to wygląda w produkcji?
Na lekcji
W produkcji
Status
try wokół int(input())
Formularz płatności: gdy w polu „kwota” nie ma liczby, strona pokazuje komunikat przy polu zamiast się zamknąć
codziennie
except FileNotFoundError
Aplikacja przy starcie czyta plik ustawień; gdy go nie ma, tworzy domyślny i działa dalej
standard
Czerwony komunikat
Serwer zapisuje cały ślad błędu do dziennika dla programisty, a użytkownikowi pokazuje jedno zdanie
standard w firmach
except bez nazwy typu
Na przeglądzie kodu odrzucane, bo ukrywa również literówki i błędy, o których nikt się nie dowie