Kihagyás

Kivételkezelés

A kivétel fogalma

A kód futása során bekövetkezhet olyan nem várt esemény, amely meggátolja a program futását az adott blokkban. Pythonban ebben az esetben úgynevezett kivétel dobódik. A kivétel lényegében egy beépített Python objektum, amely egy hibát reprezentál.

Példa: A nullával való osztás ZeroDivisionError típusú kivételt eredményez

1
2
eretnekseg = 5 / 0
print("Angry matematikus noises...")

Kimenet

Traceback (most recent call last): File "main.py", line 1, in <module> valami = 5 / 0 ZeroDivisionError: division by zero

A Pythonban számos beépített kivételosztály létezik. Ezek a kivételosztályok egy öröklődési hierarchiát alkotnak, amit az alábbi ábrán láthatunk.

Kivétel dobása

Pythonban a raise utasítás segítségével mi is dobhatunk manuálisan egy kivétel objektumot. A raise kulcsszó után meghívjuk annak a kivételosztálynak a konstruktorát, amilyen típusú kivételt el szeretnénk dobni.

1
raise Exception()   # Exception típusú kivétel dobása

A beépített kivételeknek kétféle konstruktoruk van: egy default (paraméter nélküli) és egy, ami egy szöveget vár paraméterül ("hibaüzenet"). Az utóbbi főként akkor lehet hasznos, ha a szöveges paramétert később fel szeretnénk használni.

1
raise Exception("Valamit elszúrtunk...")

Pythonban (Javával ellentétben) sehol sem kell jelezni a kivétel dobását.

Kivételek elkapása

Ha valahol el lett dobva egy kivétel, akkor azt el is tudjuk kapni.

Pythonban a try, except és finally utasításokat használjuk a kivételkezelésre. Ezek ugyanúgy működnek, mint Javában a try, catch és finally kulcsszavak.

1
2
3
4
5
6
7
8
try:
    # a kód azon része, ahol kivétel dobódhat
except ExceptionType as e:
    # ExceptionType típusú kivétel elkapása (e-ként hivatkozhatunk rá)
except Exception:
    # Exception típusú kivétel elkapása 
finally:
    # mindenképpen lefutó kódrész

Több except ág esetén a legelső, a dobott kivétel típusra illeszkedő fut le.

Példa: Írjunk egy osztás függvényt, amely két egész szám paramétert vár (a és b), visszatérési értéke pedig az a/b hányados! Ha nem egész típusú paramétereket kapunk vagy ha nullával szeretnénk osztani, dobjunk kivételt!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
def osztas(a, b):
    if isinstance(a, int) and isinstance(b, int):
        if b == 0:
            raise ZeroDivisionError("Ejnye, nullával nem osztunk!")
        return a / b

    raise TypeError("Egész paramétereket adj meg!")

# === kivételkezelés ===

try:
    print(osztas(5, 2))
    print(osztas(5, 0))     # ZeroDivisionError!
    print(osztas(3, 2))
except ZeroDivisionError as zde:
    print(zde)
except TypeError as te:
    print(te)
except Exception:
    print("Valami egyéb hiba történt...")
finally:
    print("--- kivételkezelés vége ---")

Kimenet

2.5 Ejnye, nullával nem osztunk! --- kivételkezelés vége ---

Példa: A Szuperhos osztály, amelynek konstruktorában kivételt dobunk, ha a szuperero paraméter értéke negatív.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Szuperhos:
    def __init__(self, nev, szuperero=50):
        if szuperero < 0:
            raise Exception("A szupererő értéke nem lehet negatív!")
        else:
            self._nev = nev
            self._szuperero = szuperero

            print(self._nev + " létrehozva (szupererő: " + str(self._szuperero) + ")")

    # ...

# === kivételkezelés ===

try:
    hos1 = Szuperhos("Hulk", 80)
    hos2 = Szuperhos("Vasember", 40)
    hos3 = Szuperhos("Pokember", -1)        # Exception!
except Exception as e:
    print(e)

Kimenet

Hulk létrehozva (szupererő: 80) Vasember létrehozva (szupererő: 40) A szupererő értéke nem lehet negatív!

Saját kivételosztály

Ha szeretnénk, akkor Pythonban akár saját kivételosztályt is írhatunk. Ezt valamely létező kivételosztályból kell származtatnunk (például az Exception ősosztályból).

Példa: Saját kivételosztály írása

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class NincsPisztaciaException(Exception):
    def __init__(self, uzenet):
        self.uzenet = uzenet
        super().__init__(self.uzenet)   # ősosztály konstruktorának meghívása

try:
    fagyi_izek = ["csoki", "vanília", "szamóca", "málna", "karamell"]
    if "pisztácia" not in fagyi_izek:
        raise NincsPisztaciaException("Elfogyott a pisztácia!")
except NincsPisztaciaException as npe:
    print(npe)

Kimenet

Elfogyott a pisztácia!


Utolsó frissítés: 2021-09-13 14:05:13