13 Kivételkezelés (Hibák kezelése)
Bármilyen ügyes programozó is vagy, a programjaid a való világban találkozni fognak egy nagyon kiszámíthatatlan tényezővel: a felhasználóval.
Képzeld el, hogy írsz egy programot, ami bekéri a felhasználó életkorát, hogy számoljon vele. A gép várja a számot, de a felhasználó véletlenül (vagy szándékosan) betűkkel beírja, hogy "tizenkettő". Mivel a szöveget nem lehet számként kezelni, a programod azonnal hibaüzenettel összeomlik (szaknyelven: elszáll). Ezt a fajta futási idejű hibát kivételnek (exception) nevezzük.
A modern programozásban a mi feladatunk felkészülni ezekre a kivételekre, és kulturáltan lekezelni őket.
13.1. A try - except blokk
A Python egy nagyon elegáns megoldást kínál a hibák kivédésére: ez a try (próbáld meg) és az except (kivétel, azaz "kivéve ha hiba történik") blokk.
A logikája a következő: a "veszélyes" kódot, ami hibát okozhat, betesszük a try blokkba. Ha minden rendben megy, a gép végrehajtja. De ha hiba történik, a program nem omlik össze, hanem azonnal átugrik az except blokkba, és végrehajtja az ott lévő "mentő" utasításokat.
Példa a védelem nélküli kódra (veszélyes):
szam = int(input("Kérek egy számot: "))
# Ha ide beírom, hogy "alma", a program azonnal összeomlik egy ValueError hibával!
print(f"A szám duplája: {szam * 2}")
Ugyanez a kód try-except védelemmel (biztonságos):
try:
# Ezt a részt próbálja meg végrehajtani a gép
szam = int(input("Kérek egy számot: "))
print(f"A szám duplája: {szam * 2}")
except:
# Ide csak akkor ugrik, ha a fenti 'try' részben BÁRMILYEN hiba történt!
print("Hiba! Kérlek, számjegyeket adj meg betűk helyett!")
print("A program futása zavartalanul folytatódik...")
13.2. Konkrét hibatípusok elkapása
Az előző példában az except minden elképzelhető hibát elkapott. Sokszor azonban pontosan tudni akarjuk, mi romlott el, hogy megfelelő üzenetet adhassunk a felhasználónak.
Például egy osztásnál két dolog is elromolhat: vagy nem számot ad meg a felhasználó, vagy véletlenül nullával akar osztani (amit a matematikában nem lehet).
A Pythonban minden hibának megvan a maga "hivatalos" neve. Íme a leggyakoribbak:
| Hiba neve (Típus) | Mikor fordul elő? | Példa |
|---|---|---|
ValueError |
Rossz típusú értéket akarunk átalakítani. | Szöveget akarunk int()-be tenni (pl. "alma"). |
ZeroDivisionError |
Nullával próbálunk meg osztani. | 10 / 0 |
TypeError |
Nem összeillő típusokkal végzünk műveletet. | Szöveghez adunk számot ("Kecske" + 5). |
FileNotFoundError |
Olyan fájlt akarunk megnyitni olvasásra, ami nem létezik. | open("nincsilyen.txt", "r") |
A programban több except ágat is megadhatunk egymás után, attól függően, hogy milyen hibát várunk!
try:
oszto = int(input("Mennyivel osszam el a 100-at? "))
eredmeny = 100 / oszto
print(f"Az eredmény: {eredmeny}")
except ValueError:
print("Hiba: Nem számot adtál meg!")
except ZeroDivisionError:
print("Hiba: Nullával nem lehet osztani!")
ValueError ág fut le. Ha nullát, akkor a ZeroDivisionError ág. A program egyik esetben sem omlik össze!
13.3. A bolondbiztos beolvasás (Gyakorlati trükk)
Az egyik leggyakoribb feladat, hogy addig kérdezzük a felhasználót, amíg végre hajlandó helyes adatot (például egy valódi számot) megadni. Ezt a while ciklus és a try-except kombinálásával érhetjük el a legkönnyebben.
A break (megszakítás) parancs csak akkor hajtódik végre, ha az előtte lévő beolvasás sikeres volt. Ha hiba történik, a gép egyből az except-re ugrik, kihagyja a break-et, és a ciklus kezdődik elölről!
while True: # Végtelen ciklus, ami addig fut, amíg ki nem "törünk" belőle
try:
eletkor = int(input("Kérlek, add meg az életkorod: "))
break # Ha sikerült a beolvasás, megszakítjuk a ciklust!
except ValueError:
print("Hibás adat! Kérlek, számjegyekkel írd be a korod!")
print(f"Szuper, a megadott kor: {eletkor}")
💻 Feladatok
- Biztonságos fájlolvasás: Írj egy programot, amely megpróbál megnyitni egy
titkok.txtnevű fájlt olvasásra ("r"móddal), és kiírja a tartalmát! Mivel ez a fájl nem létezik a gépeden, a program normál esetben összeomlana. Használjtry-exceptblokkot és kapd el aFileNotFoundErrorhibát, majd írd ki a képernyőre: "A keresett fájl sajnos nem található!" - Okos számológép: Készíts egy programot, amely bekér két számot a felhasználótól (
inputésintsegítségével)! A gép írja ki a két szám összegét és hányadosát (osztását)!- Védd le a programot
ValueErrorellen (ha betűt írna be valamelyik szám helyett)! - Védd le a programot
ZeroDivisionErrorellen (ha a második szám nulla lenne)!
- Védd le a programot
- Bolondbiztos magasság: A fenti "bolondbiztos beolvasás" példa alapján készíts egy
whileciklust, amely addig kéri a felhasználótól a magasságát (méterben, tehátfloattizedestörtként), amíg egy érvényes számot nem ír be (pl.1.75)! Ne felejtsd el figyelmeztetni, ha rossz karaktereket vagy betűket használ!