Informatika2-2013/Gyakorlat10

A MathWikiből
(Változatok közti eltérés)
 
(egy szerkesztő 15 közbeeső változata nincs mutatva)
1. sor: 1. sor:
 
== Osztályok ==
 
== Osztályok ==
 +
 +
*[https://docs.google.com/document/d/1DfqcaiLkpQTjBn2Nh2-CmySvduOJmTHcDKqwsiKRz5I/edit codes in the clouds]
  
 
*Az osztályok egységbe zárnak és a felesleges információt elrejtik.
 
*Az osztályok egységbe zárnak és a felesleges információt elrejtik.
*Az osztályok metódusokat és változókat tartalmaznak.
+
*Az osztályok metódusokat és változókat tartalmaznak. Metódusokat tekintsük osztályokon belüli függvényeknek.
 
*Tekintsünk erre úgy, hogy a kód egy részét (mind tárolókat, mind a függvényeket nézve) összefogjuk.
 
*Tekintsünk erre úgy, hogy a kód egy részét (mind tárolókat, mind a függvényeket nézve) összefogjuk.
*Egy objektum egy osztály konkrét megvalósítása.  
+
*Egy objektum egy osztály konkrét megvalósítása.
  
 
+
Egy metódust az alábbi módon definiálunk pythonban:
 
+
Saját osztályt így definiálhatunk:
+
 
<python>
 
<python>
class MyClass:
+
class Foo:
    valt = 5
+
  def setx(self, x):
   
+
      self.x = x
    def fv(self):
+
  def bar(self):
        return self.valt * 2
+
      print self.x
 
</python>
 
</python>
Itt a '''valt''' változó az osztályhoz tartozik, így elérhetjük például """MyClass.valt"""-al. Viszont, ha a '''fv'''-t próbáljuk hasonlóképpen elérni hibába ütközünk. Ez azért van, mert az osztályt nem közvetlenül szokták használni, hanem példányosítják:
+
* Itt a lényeges dolog a self változó, ami mindig az első argumentuma a metódusnak. Ez mindig a konkrét megvalósított objektumot jelöli. Tehát külön értékadás nélkül self.x az osztályon (objektumon) belüli x változó, aminek az értékét állítjuk be a setx függvénnyel.
 
+
* Az alábbi módon hozhatunk létre objektumokat és hívhatjuk meg azok metódusait:
<python>
+
<Python>
x = MyClass()       # létrehozunk egy MyClass típusú objektumot
+
f = Foo()
x.fv()               # így már menni fog a fv metódus
+
f.setx(5)
</python>
+
f.bar()
 
+
Foo.setx(f,5)
Így definiált objektumokhoz késõbb is hozzávehetünk még adattagokat:
+
Foo.bar(f)
 
+
</Python>
<python>
+
* Fontos, hogy Pythonban futási időben is változhatnak az osztályhoz tartozó változók:
x = MyClass()
+
<Python>
x.ujValt = "Valami"
+
del f.x
print x.ujValt
+
</Python>
#print MyClass.ujValt ez nem menne, mert az ujValt az x objektumhoz tartozik és nem az osztályához
+
* Itt tehát magát a változót töröljük.
</python>
+
* Minden egyes objektum mögött a háttérben létezik egy szótár, ami tartalmazza az osztály elemeit:
 
+
<Python>
Osztályoknak léteznek speciális metódusai, ezekrõl részletesebben következõ gyakorlaton lesz szó, most nézzük csak az '''__init__'''-et. Ez az a függvény, ami meghívódik amikor létrehozunk egy ilyen típusú objektumot, azaz pl az '''x = MyClass()''' parancsnál ez hívódik.
+
g = Foo()
Aki nem hiszi próbálja lefuttatni ezt:
+
vars(g)
<python>
+
g.__dict__
 +
</Python>
 +
* Konstruktornak hívjuk azt a metódust, ami az objektum létrehozásával együtt hívódik meg:
 +
<Python>
 
class Test:
 
class Test:
 
     def __init__(self):
 
     def __init__(self):
 
         print "Mostmar elhiszed?"
 
         print "Mostmar elhiszed?"
 
+
 
x = Test()
 
x = Test()
</python>
+
</Python>
 +
* A destruktor konzisztens módon az objektum  törlésével együtt hívódik meg.
 +
== Feladatok ==
  
Mi ez a '''self''' amit mindig megadunk a metódusoknak? Ezzel a változóval hivatkozhatunk magára az objektumra amin meghívtuk az adott metódust, példából jobban érthetõ:
+
=== 1. feladat ===
 +
* Változtasd az osztály és objektumszintű változókat az előadásnak megfelelő módon.
 +
* Előadásanyag: [https://docs.google.com/presentation/d/1F1kRViEjY9B-XDJmpJ9uuUQNA8CAnaxE4EFhczo7n70/edit?usp=sharing dia]
 
<python>
 
<python>
class Pelda:
+
>>> class A:
    def fv(self, szam):
+
...  pass
        self.v = szam
+
...
 
+
>>> A.v1 = 10
x = Pelda()
+
>>> x=A() # létrehozok két példányt
y = Pelda()
+
>>> y=A()
x.fv(5)
+
>>> x.v1  # példányon belül is elérem az osztály szintű változót
y.fv(15)
+
10
 
+
>>> x.v1 = 34 # itt viszont létrehozok egy példány szintűt aminek a neve felülírja az osztály szintűt
print x.v
+
>>> y.v1
print y.v
+
10
 
+
>>> x.v1
# Ez a fv metódus olyan volt, mintha már az x létrehozása után azt írtam volna, hogy x.v = 5
+
34
 +
>>> A.v1
 +
10
 +
>>> A.v1 = 12 # itt az osztályszintű változót változtatjuk
 +
>>> x.v1 # mivel felülírtuk a v1-t az x példányban így ezen már nincs hatása
 +
34
 +
>>> y.v1
 +
12
 +
>>> A.v1
 +
12
 
</python>
 
</python>
  
Amint látjátok a self változót nem kell nekünk átadnunk amikor meghívjuk a metódusokat, ez automatikusan megtörténik. (Pelda.fv(x, 5)  <=>  x.fv(5))
+
=== 2. feladat ===
 
+
[http://math.bme.hu/~kkovacs/info2/matrix_%20resz.py link]
Ha az '''__init__''' függvény nem csak a self-et, hanem más változókat is kap, akkor ezeket is meg kell adnunk, pl:
+
* Írj mátrix osztályt az alábbi metófudokkal:
 
<python>
 
<python>
class Test:
+
  class Matrix:
     def __init__(self, szam):
+
     def const(self,n,x):
        self.x = szam
+
      ...
 
+
    def zeros(self,n):
x = Test(15)
+
      ...
print x.x
+
    def printer(self):
 +
      ...
 +
    def set(self,i,j,x):
 +
      ...
 +
    def get(self,i,j):
 +
      ...
 +
    def hasValue(self,i,j):
 +
      ...
 +
    def getLine(self,i):
 +
      ...
 +
    def pow(self):
 +
      ...
 +
    def product(self,v)
 
</python>
 
</python>
 
+
* próbálj meg hibakezelést beépíteni a függvényekbe (try --- except)
==== 5. Osztály feladat - Telefonkönyv ====
+
 
+
Egészítsétek ki a következõ osztályt, hogy egy ilyen objektum létrehozásakor megadhassunk neki két listát amikben nevek és telefonszámok szerepelnek, ezeket tárolja el adattagként. Valamint a '''hozzavesz''' metódusa vegyen hozzá egy nevet és a hozzá tartozó telefonszámot a listákhoz.
+
 
+
<python>
+
class Telefonkonyv:
+
    def __init__(self, nevek, telefonszamok):
+
        pass
+
   
+
    def hozzavesz(self, nev, telefonszam):
+
        pass
+
</python>
+
 
+
A '''pass''' kulcsszó csak azért van ott, mert pythonban minden blokkban kell lennie legalább egy parancsnak. A '''pass''' nem csinál semmit csak kitölti a teret.
+

A lap jelenlegi, 2013. május 2., 23:52-kori változata

Tartalomjegyzék

Osztályok

  • Az osztályok egységbe zárnak és a felesleges információt elrejtik.
  • Az osztályok metódusokat és változókat tartalmaznak. Metódusokat tekintsük osztályokon belüli függvényeknek.
  • Tekintsünk erre úgy, hogy a kód egy részét (mind tárolókat, mind a függvényeket nézve) összefogjuk.
  • Egy objektum egy osztály konkrét megvalósítása.

Egy metódust az alábbi módon definiálunk pythonban:

class Foo:
   def setx(self, x):
      self.x = x
   def bar(self):
      print self.x
  • Itt a lényeges dolog a self változó, ami mindig az első argumentuma a metódusnak. Ez mindig a konkrét megvalósított objektumot jelöli. Tehát külön értékadás nélkül self.x az osztályon (objektumon) belüli x változó, aminek az értékét állítjuk be a setx függvénnyel.
  • Az alábbi módon hozhatunk létre objektumokat és hívhatjuk meg azok metódusait:
f = Foo()
f.setx(5)
f.bar()
Foo.setx(f,5)
Foo.bar(f)
  • Fontos, hogy Pythonban futási időben is változhatnak az osztályhoz tartozó változók:
del f.x
  • Itt tehát magát a változót töröljük.
  • Minden egyes objektum mögött a háttérben létezik egy szótár, ami tartalmazza az osztály elemeit:
g = Foo()
vars(g)
g.__dict__
  • Konstruktornak hívjuk azt a metódust, ami az objektum létrehozásával együtt hívódik meg:
class Test:
    def __init__(self):
        print "Mostmar elhiszed?"
 
x = Test()
  • A destruktor konzisztens módon az objektum törlésével együtt hívódik meg.

Feladatok

1. feladat

  • Változtasd az osztály és objektumszintű változókat az előadásnak megfelelő módon.
  • Előadásanyag: dia
>>> class A:
...   pass
... 
>>> A.v1 = 10
>>> x=A() # létrehozok két példányt
>>> y=A()
>>> x.v1  # példányon belül is elérem az osztály szintű változót
10
>>> x.v1 = 34 # itt viszont létrehozok egy példány szintűt aminek a neve felülírja az osztály szintűt
>>> y.v1
10
>>> x.v1
34
>>> A.v1
10
>>> A.v1 = 12 # itt az osztályszintű változót változtatjuk
>>> x.v1 # mivel felülírtuk a v1-t az x példányban így ezen már nincs hatása
34
>>> y.v1
12
>>> A.v1
12

2. feladat

link

  • Írj mátrix osztályt az alábbi metófudokkal:
  class Matrix:
    def const(self,n,x):
      ...
    def zeros(self,n):
      ...
    def printer(self):
      ...
    def set(self,i,j,x):
      ...
    def get(self,i,j):
      ...
    def hasValue(self,i,j):
      ...
    def getLine(self,i):
      ...
    def pow(self):
      ...
    def product(self,v)
  • próbálj meg hibakezelést beépíteni a függvényekbe (try --- except)
Személyes eszközök