A mai bejegyzés egy kicsit rendhagyó lesz abból a szempontból, hogy általában nem írok olyasmiről, amiről található jó a magyar irodalomban. A Python nyelvről pedig van, és a kivételkezelésről is. Az előzőek elhangzottak korábban azon a cégen belüli Python tréningen, amit tartok, és a kollégák szerint vicces. Viccesen írni erről a témáról pedig szvsz nehéz, szóval úgy döntöttem, ezúttal kivételt teszek.
Az unalmas rész
Mi a kivétel? A kivétel egy olyan esemény, ami a program végrehajtása során megakasztja a normál végrehajtást. Lényegében egy olyan szituáció, amivel a Python kód nem tud megbirkózni, és megszakítva a futást egy “exception”-t, kivételt add vissza. A kivétel az a Python objektum, ami ezt a adott hibát jelképezi.
Ha nem kezeljük azonnal a szituációt amikor a Python fordító a kivételt dobta, a program leáll.
OK. Mit jelent ez?

A Világ amiben élünk törött. És vele együtt a mi kis Python kódunk is. Bárki aki kódot ír, muszáj látnia, hogy lehetetlen olyan kódot írni, ami mindig helyesen működik.
Mit lehet tenni?
A Python nyelvben a try … except… szintaxist használjuk a kivételek kezelésére. A try részben írjuk azt a kódot, amiről feltételeztük, hogy néha nem fog működni. Az except rész pedig részletezi mit tegyünk, ha a pesszimista forgatókönyv valósul meg, és a fordító tényleg kivételt dob. Egy egyszerű példa:
try:
# megnyitunk egy fájlt, ez vagy létezik vagy nem
fh = open("testfile", "rb")
except IOError:
# a fájl nem létezik ami egy kivételt, nevezetesen IOError dob
print("Hiba: a fájl nem létezik vagy nem olvasható!")
A nyelvben még definiálva van a finally eljárás is, ami minden esetben lefut, attól függetlenül, hogy a try rész működött vagy nem:
try:
# megnyitunk egy fájlt, ez vagy létezik vagy nem
fh = open("testfile", "rb")
except IOError:
# a fájl nem létezik ami egy kivételt, nevezetesen IOError dob
print("Hiba: a fájl nem létezik vagy nem olvasható!")
finally:
print("Valami amit attól függetlenül teszünk, hogy a fájl létezik vagy nem")
Lehetőségünk van a különböző típusú kivételeket más-más módon kezelni:
# egy függvény
def teszt(a):
return a
# milyen véletlenszerű akciót teszünk a try részben
import numpy as np
what_should_i_do = np.random.randint(1,4,1)
try:
if what_should_i_do == 1:
# megnyitunk egy fájlt
fh = open("testfile", "rb")
elif what_should_i_do == 2:
# nullával való osztás
1/0
else:
teszt()
except IOError as e:
print("Hiba: a fájl nem létezik vagy nem olvasható!"")
except ZeroDivisionError as e:
print("Hiba: nullával való osztáso")
except Exception as e:
print("Hiba, minden egyéb kivétel: ", str(e))
Mi legyen a try részben?
Az mind szép és jó, de van itt egy alapvető kérdés: Mi kerüljön a try szakaszba? Szögezzünk le valamit: A kivételek tulajdonsága, hogy nem lehet biztosan előre megjósolni. Bizonyos esetekben számíthatunk rá, hogy valami nem fog működni, mint a fenti példában a fájl megnyitása. De ne ringassuk magunkat abban a hitben, hogy minden egyes lehetséges probléma eszünkbe fog jutni.
Ha ezt elfogadjuk akkor három út áll előttünk. Ezeket fogjuk most részletezni, de előtte létrehozunk egy osztályt, aminek segítségével szemléltetem a megközelítések közötti különbségeket.
A példa kedvért mondjuk legyen ez a Life (“Élet”) osztály, ami realizálása a your_live (“a te életed”) objektum lesz. Ezenkívül még legyen egy kivételünk, Frustration (Frusztráció), amit bizonyos esetekben ez az osztály dob:
# A saját Frusztáció kivételünk
class Frustration(Exception):
def __init__(self, message):
# Call the base class constructor with the parameters it needs
super().__init__(message)
# Az Élet osztály
class Life:
# a komunkiáció másokkal nem az erős oldala az Élet osztálynak, mindig Frusztrációt eredményez
def connect_to_others(self, thinks_you_are_say):
raise Frustration("You are and idiot")
# néha az Élet osztály futtatása során butaságokat teszünk csak úgy magunktól
def make_stupid_things(self):
return 10/0
# néha meg jó dolgokat, ilyenkor valami boldogságot sugárzó zene a jutalom
def make_good_things(self, msg):
import random
happy_music = ["https://www.youtube.com/watch?v=EKGUJXzxNqc",
"https://www.youtube.com/watch?v=JebowNHkA_M",
"https://www.youtube.com/watch?v=tVQtKyeWisQ",
"https://www.youtube.com/watch?v=D5Y11hwjMNs"]
random.shuffle(happy_music)
return happy_music[0]
your_life = Life()
Az egész életedet buborékfóliába csomagolod
Ez egy kényelmes megoldásnak tűnik, de a valóságban önámítás.
Kódban leírva egy néz ki:
try:
your_life = Life()
import numpy as np
what_should_i_do = np.random.randint(1,4,1)
print(what_should_i_do)
if what_should_i_do == 1:
your_life.connect_to_others("Szép vagy!")
elif what_should_i_do == 2:
print( your_life.make_good_things("Hajléktalanok segítése.") )
else:
your_life.make_stupid_things()
except Frustration as e:
try:
raise("https://www.babelmatrix.org/works/hu/Ady_Endre-1877/Szeretn%C3%A9m%2C_ha_szeretn%C3%A9nek/en/1958-I_want_to_be_loved")
except:
print("https://www.youtube.com/watch?v=RFqPuscYk_Y")
except Exception as e:
print("https://www.youtube.com/watch?v=ltVOXz4mxOo")
Mint látható bármit tehetünk mindig valami boldog zenét hallgathatunk.
A kommunikációt másokkal buborékfóliába csomagolod, de őszinte vagy magadhoz
Mint a fenti osztálydefinícióból tudjuk a kommunikáció másokkal valami hasonló:

Vesztet csata, de ezzel nem tehetünk semmit. Néha meg kell próbálnunk.
De lássuk be, az Élet nem csak ebből áll, néha mi magunk is teszünk jó vagy rossz dolgokat. A korábbi megközelítéssel ellentétben ezeket az eseteket nem védjük kivételkezeléssel. Fájdalmas lesz amikor saját hibáinkkal szembesülünk de legalább őszinték vagyunk magunkhoz.
Kódban:
your_life = Life()
import numpy as np
what_should_i_do = np.random.randint(1,4,1)
if what_should_i_do == 1:
your_life.make_stupid_things()
elif what_should_i_do == 2:
print( your_life.make_good_things("Képeslap küldése politikai foglyoknak.") )
else:
try:
your_life.connect_to_others("Jó embernek tartalak!")
except:
print("https://youtu.be/2W6zK9givao")
B*meg, nem érdekel, ha valami rossz akkor legyen rossz
Ha valami nem működik akkor hagyjuk, hogy összeomoljon. Sajnos ez a hozzáállás nem fizet jól. Lényegében arra kényszeríted a többieket, hogy próbálják megjavítani a közös Életeteket. Ezt pedig általában nem szeretik az emberek.
Kódban:
your_life = Life()
import numpy as np
what_should_i_do = np.random.randint(1,4,1)
if what_should_i_do == 1:
your_life.make_stupid_things()
elif what_should_i_do == 2:
print( your_life.make_good_things("Megdicséred a gyereket amikor jót tesz.") )
else:
your_life.connect_to_others("Érdekes amit mondasz.")
Vagyis lényegében nem használunk kivételkezelést.
Összegzés
Nagyából ennyit szeretem volna írni a kivételkezelésről, remélem hasznos. Még lehetne írni arról, hogy miként hozzunk létre saját kivételeket, de fölöslegesnek tartom ezt külön részletezni, fentebb a Frustration és Life osztályok definiálásánál ez látható.