Jason. Cała informatyka w jednym miejscu!

Wchodzimy na wyższy "level"! Python wspiera przechwytywanie wyjątków i w dzisiejszym artykule poruszę właśnie ten temat. Poznacie znaczenie trzech nowych słów kluczowych mających związek z wyjątkami: "try", "except" oraz "finally". Ponadto, dowiecie się w jakim celu się je stosuje. Zajrzyjcie do wnętrza wpisu, dowiedzcie się informacji i zacznijcie wdrażać kolejną wiedzę w życie!

SYTUACJE U KTÓRYCH NIEZBĘDNE JEST PRZECHWYTYWANIE WYJĄTKÓW

Wyobraźcie sobie taką historię. Dostajecie rachunek za prąd. Kosztuje on sporo pieniędzy, ale w tym miesiącu będzie Was jeszcze stać na jego opłacenie. Płacicie. Odnotowujecie bieżący stan gotówki. Miesiąc później dostajecie kolejną zapłatę do uregulowania. Tym razem jednak z opłaty nici, gdyż nie starczy gotówki na pokrycie należności. Dzwonicie do przyjaciela i prosicie o pożyczkę. Udziela Wam jej. Kwota zostaje pokryta, a kilka dni później po otrzymaniu premii w pracy, zwracacie dług przyjacielowi. Odnotowujecie stan po raz drugi.

Oto historyjka prezentująca wystąpienie wyjątku ujmując to programistycznie. Rozbijmy to sobie na podpunkty:

  1. otrzymanie rachunku za prąd,
  2. próba opłacenia otrzymanego rachunku,
    1. opłacenie należności (przypadek oczekiwany),
    2. zwrócenie się z prośbą do przyjaciela o pożyczkę (przypadek wyjątkowy),
  3. zanotowanie bieżącego stanu gotówki.

Zaczynacie już widzieć ten wyjątek? Jak to w życiu, przeważnie stać nas na rachunki, ale może nam się w którymkolwiek momencie "powinąć noga" i wtedy prosimy kogoś o pomoc (dla łatwiejszego zrozumienia, pomijam scenariusz gdy nie mamy do kogo się zwrócić :(). Zatem, próba opłacenia rachunku może zakończyć się wyjątkiem przejawiającym się zasileniem przy pomocy innego źródła, jeżeli nas na to nie stać. A teraz, programowanie.

WYJĄTEK OKIEM PROGRAMISTY

Przechwytywanie wyjątków polega na sporządzeniu odrębnego bloku kodu dla każdej tzw. "sytuacji ryzykownej", czyli korzystamy z funkcji lub obiektów, które mogą sobie nie poradzić w pewnych skrajnych przypadkach podczas wykonywania swoich czynności "na co dzień". Prostym przykładem "ze świata informatycznego", jest próba odczytania pliku tekstowego, którego nie ma. Klasa została tak napisana, że domyślnie ona "zakłada", że otwierany plik istnieje. Jednak, po uruchomieniu przykładowego programu, wystawiamy go na próbę, a pliku nie ma! I co wtedy? Program komputerowy nie jest człowiekiem i sam nie znajdzie drogi alternatywnej na bezbolesne rozwiązanie napotkanego problemu. Jedyne co może zrobić, to zgłosić wyjątek.

JAK "WYGLĄDA" WYJĄTEK?

"Domyślne" zachowanie zgłoszenia wyjątku to przerwanie wykonywania dalszych instrukcji i wyrzucenie na ekran powłoki informacji o wyjątku, chociaż Python "ubiera" to w określanie jako "błąd" mimo tego, że "wyjątek" a "błąd", to nie to samo! Dlaczego? Z dwóch przyczyn:

  1. wyjątek powstaje na wskutek doświadczenia sytuacji nieoczekiwanej lub z błędnego zapisu w kodzie, błąd z powodu problemu dotyczącego zasobów systemu np. przepełnienie stosu,
  2. wyjątek wysyła sygnał, który można przechwycić i próbować "uratować sytuację", przy błędzie jest komunikat i zamknięcie programu "bez pytania o zdanie".

Treść wyjątku przeważnie składa się z następujących elementów:

  • słowa "traceback" (ang. ostatnie wywołanie/transakcja),
  • pliku skryptowego w jakim doszło do zgłoszenia wyjątku,
  • konkretnej linijki kodu w jakiej powstał problem,
  • "przytoczenia" treści danej linijki kodu uważanej za przyczynę zgłoszenia wyjątku,
  • "typu" wyjątku z krótkim opisem.

Mogą być takie wyjątki, które różnią się wyglądem komunikatu, natomiast zdecydowana większość będzie składała się z powyższych informacji.

Wyjątek dzielenia przez zero w Pythonie

Przykładowa treść wyjątku polegającego na próbie dzielenia liczby przez zero.

NAJLEPSZE ZASTOSOWANIA?

Przechwytywanie wyjątków powinno być jak najbardziej wykorzystywane wokół każdego kodu, który jest "ryzykowny" (dana instrukcja może się "wysypać", nie poradzić sobie z nieoczekiwaną sytuacją). Dla przykładu:

  • otwieranie nieistniejącego pliku powinno wyświetlić komunikat "mówiący po ludzku", że nie znaleziono pliku o podanej nazwie,
  • zmiana motywu/skórki programu na inną przy użyciu wadliwej konfiguracji mogłaby zakończyć się przywróceniem wyglądu domyślnego "wszczepionego" w program.

I tak dalej...

"TRIADA" SŁÓW KLUCZOWYCH

Przed Wami, trzy słowa kluczowe które zostały zbudowane na myśl o programowaniu bezpiecznego kodu źródłowego. Są to "try", "except" oraz "finally". Polecimy sobie po kolei:

try

Słowo "try" (ang. próbować) to jest miejsce, w którym zawiera się instrukcję/obiekt/funkcję/cokolwiek innego mogącego zgłosić sytuację nieoczekiwanąPo słowie "try", wstawiamy dwukropek tak samo, jak to było przy instrukcji warunkowej czy pętli "while":

try:
    # dowolne instrukcje

Samo "try" nie wystarczy na przechwytywanie wyjątków. Potrzebna jest nam druga część czyli...

except

"except" (ang. poza/z wyłączeniem/z wyjątkiem) to kolejny OSOBNY blok kodu wykonujący się wyłącznie w sytuacji, gdy przechwycono od programu sygnał, że coś poszło nie tak. Ta część musi iść w parze z poprzednią, czyli interpreter "puści" ten program dopiero jak zobaczy i "try", i "except", i w tej samej kolejności! Tak wygląda kod:

except:
    # dowolne instrukcje

Te słowa kluczowe są wymagane, aby istniały one razem, jeden pod drugim nierozłącznie. Ostatnie słowa o trzecim:

finally

Do dyspozycji mamy jeszcze "finally" (ang. wreszcie/w końcu). To wyjątkowo jest opcjonalne i wykonuje się niezależnie od wyniku. Bez względu na to, czy zgłoszono wyjątek, czy też nie, ten blok kodu wykonuje się niezależnie od sytuacji. Pamiętacie to notowanie obecnego stanu gotówki z przykładu na samym początku artykułu? To jest właśnie sytuacja którą można spotkać w obu przypadkach: kiedy starczyło albo kiedy nie starczyło na opłacenie rachunku. Celowo go wtrąciłem, żebyście zobaczyli taki abstrakcyjny przykład wzięty z życia :). Wzór jest następujący:

finally:
    # dowolne instrukcje

Podsumowując, cały blok na przechwytywanie wyjątków od stóp do głów musi się prezentować w takiej kolejności:

try:
    # instrukcje mogące zgłosić wyjątek
except:
    # instrukcje wykonywane w momencie zgłoszenia wyjątku
finally:
    # instrukcje wykonywane niezależnie od sytuacji

z czego dwa pierwsze są obowiązkowe, a ostatnie nie musi występować.

Przechwytywanie wyjątku dzielenia przez zero w Pythonie
Działanie przechwytywania wyjątku dzielenia przez zero w Pythonie

Obsługa wyjątków to podstawa do pisania bezpiecznego kodu radzącego sobie w sytuacjach skrajnych.


Przechwytywanie wyjątków to dosyć rozległy temat, o którym można by spokojnie napisać jeszcze kilka sztuk solidnych treści naukowych. Myślę, że na tę chwilę tyle informacji wystarczy dla każdego początkującego ;).

PODOBNE ARTYKUŁY