Python kezdőknek kurzus 7. lecke
A Ubuwiki wikiből
Objektumorientált programozás
Ez a lecke a korábbiaknál haladóbb jellegű és az objektumorientált programozásról szól. Nem feltétlenül szükséges tudni az objektumorientáltságról, ha egyszerűbb szkripteket szeretnénk írni. Viszont hasznos ismerni a Python objektumokat, ha olvashatóbb és könnyebben érthető Python programokat szeretnénk írni. Emellett segít abban is, hogy megértsük a már létező Python csomagok működését illetve használatát. Leginkább grafikus felület kódjánál kell gyakran objektumokkal dolgozni - mindegy ugyanis, hogy milyen eszközt használunk, egy grafikus felület esetén az ablakok, dialógusok, gombok, címkék a legtöbb esetben objektumok lesznek.
Tartalomjegyzék
Ha a mai leckét zavarosnak találod, ne pánikolj. Ha még nem találkoztál objektumorientált programozással, eltart egy ideig, míg megszokod. Amíg tudod mit jelent az “osztály” és a “self”, nem szükséges, hogy minden részletre emlékezz.
Objektumok
Tehát mi is az az objektum?
Az objektum egy adattípus, melynek van néhány saját adata és néhány dolog, ami az adatokkal csinál valamit. Lehet nagyon egyszerű, mint például egy egész szám (mondjuk 42), vagy lehet olyan bonyolult, mint egy böngésző ablaka.
Tegyük fel, hogy van egy lista objektum, például a sajat_lista = [ 1, 2, 3 ]
. Ez a saját adat - minden elem a listában, és még valamennyi járulékos információ, például az, hogy hány elem van a listában.
Van néhány egyéb egyedi függvény a listához. Mondhatjuk ugyanis azt, hogy sajat_lista.append(4)
, ami egy negyedik elemet ad a lista végéhez, vagy a sajat_lista.insert(4)
, ami ugyanazt az elemet adja a listához, de a lista elejére helyezi el. A sajat_lista.remove(2)
töröl egy elemet, a sajat_lista.reverse()
pedig a lista elemeinek sorrendjét megfordítja.
Python3 esetén a sajat_lista.insert(0,4)
használható, amely a lista első helyére beszúrja a 4 elemet. Hasonlóan a sajat_lista.insert(3, 17)
a lista negyedik helyére szúrja be az elemet.
Az imént említett függvényeket - append, insert, remove, reverse
- tagfüggvényeknek hívjuk, mert egy adott objektum tagjai, annak tulajdonképpen részei.
Osztályok
Az objektum csak egy dolog - egy változó, amely egy sztringet tárol, egy egészet, egy szótárat. Természetesen, mint a lista vagy a szótár, akár tartalmazhat több dolgot is, de ha az egészet tekintjük, az egy dolog.
Az objektum típusa az osztály (például sztring vagy lista). Tehát amikor azt mondjuk, hogy a
sajat_lista = [ 1, 2, 3 ]
akkor a sajat_lista
egy objektum (változó), amelynek lista az osztálya (típusa).
Ha a Python parancssort használjuk, megkérdezhetjük egy változó típusát:
Python 2.x | Python 3.x |
---|---|
>>> type(sajat_lista) <type 'list'> |
>>> type(sajat_lista) <class ‘list’> |
Ha ez segít, gondolhatsz úgy az osztályra, mint a típusokra.
Osztály definiálása
Saját osztályokat is lehet definiálni. Az előző leckében szereplő egyik feladatnál szerepelt például a tanulokartya
, ezt akár osztály formájában is megvalósíthatjuk:
Python 2.x | Python 3.x |
---|---|
class Tanulokartya : def __init__(self, k, v) : self.kerdes = k self.valasz = v def nyomtat_kerdes(self) : print self.valasz |
class Tanulokartya : def __init__(self, k, v) : self.kerdes = k self.valasz = v def nyomtat_kerdes(self) : print(self.valasz) |
Ezután így készíthetsz Tanulokartya
objektumokat (az osztályból egy változót):
kartya1 = Tanulokartya("What is a baby swan called?", "cygnet") kartya2 = Tanulokartya("What is a group of larks called?", "exaltation")
Esetleg meglepődtél a nagybetűs objektum elnevezésen. Az osztályok neveit nagyon gyakran nagybetűvel kezdjük, de ez csak szokás - nem kötelező.
self
Egy új dolog, ami az objektum-orientált kódban gyakran előkerül a self
. Osztályon belül a self
mindig az aktuális objektumot jelöli. Tehát ha a kartya1 tanulókártyáról van szó, akkor a "What is a baby swan called?" kérdés a self.kerdes lesz.
Ha már programoztál más objektum-orientált nyelven, ott esetleg a this
kulcsszó jelöli a self
-et.
Minden osztályfüggvényben használni kell a self-et, mint első argumentumot. (Van néhány kivétel, de ezekkel most nem foglalkozunk.) Talán meglepő, hogy minden alkalommal be kell gépelni a self-eket (főleg, ha már találkoztál más objektum-orientált nyelvvel). Hiszen azt gondolhatjuk, a Python igazán feltételezhetné, hogy ha azt írjuk valasz, akkor az a self.valasz-t jelöli, és minden osztályfüggvénynél a self az aktuális objektumot jelöli. Ha így gondoljuk, nem vagyunk ezzel egyedül. Viszont a Python ilyen, szokjunk hozzá, hogy a self-et sokszor látni fogjuk, ahol osztályokat használunk.
Az init függvény
Nem túl hasznos, ha van osztályunk, de nem tudunk az osztályból objektumot létrehozni. Erre való az __init__
függvény (két aláhúzás van az init előtt és kettő utána).
def __init__(self, k, v) :
Az __init__
függvényt használhatjuk az osztályból származó objektumok változóinak beállítására. Egy Tanulokartya objektum nem túl hasznos, ha nincs megadva egy kérdés és egy válasz, készítsünk hát egy init függvényt k és v a paraméterekkel (ezek lesznek a kerdes és valasz értékei).
Egyéb tagfüggvények
A többi tagfüggvény is hasonlóan működik, hivatkozhatnak a self.kerdes
és self.valasz
változókra. A Tanulokartya osztályon belül lehet például ilyen változónk (sor) illetve függvényünk (kviz_felhasznalo):
Python 2.x | Python 3.x |
---|---|
sor = "=============================================" def kviz_felhasznalo(self) : print self.sor self.nyomtat_kerdes() print self.sor val = raw_input("? ") if val.strip().lower() == self.valasz.strip().lower() : print "Szep munka!" return True print "Sajnalom, a helyes valasz:", self.valasz return False |
sor = "=============================================" def kviz_felhasznalo(self) : print(self.sor) self.nyomtat_kerdes() print(self.sor) val=input(“? “) if val.strip().lower() == self.valasz.strip().lower() : print(“Szep munka!”) return True print("Sajnalom, a helyes valasz:", self.valasz) return False |
A fenti módon létrehoztunk a Tanulokartya
osztályban egy sor nevű változót, ami minden objektum esetén azonos és a kviz_felhasznalo
pedig hivatkozik rá. Most, hogy már létrehoztuk a Tanulokartya
objektumot, egy kvíz programot írni egyszerű:
kartyak = [ Tanulokartya("Hogy hívják az újszülött lovat?", "csikó"), Tanulokartya("Hogy hívják a halak csoportját?", "halraj"), Tanulokartya("Hány évbe telik, míg a Neptun megkerüli a napot?", "165"), ] while True : random.choice(kartyak).kviz_felhasznalo()
Gyakorló feladatok
1. Írjunk egy jobb ciklust úgy, hogy a tanulókártya program lépjen ki abban az esetben, ha a felhasználó ‘k’-t gépel és írjuk ki hány esetben válaszolt jól és hányszor rosszul.
Tipp: változtassuk meg a kviz_felhasznalo
függvényt úgy, hogy ne csak True vagy False visszatérési értéke legyen.
2. Írjunk egy Kviz
osztályt, ami tanulókártyákat készít és egy ciklust futtat.
3. (opcionális) írjuk újra az 5. leckében szereplő véletlen mondat generálónkat objektum-orientált módon.
Tipp: a főnevek, igék, stb listája lehet osztályváltozó, mint a fenti példában a sor
.
4. (opcionális) Találjunk ki egy jobb objektum-orientált gyakorló feladatot és oldjuk meg :-)