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.


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 Neptunusz 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 :-)

További leckék

Személyes eszközök