Informatika2-2012/Eloadas10
Stma (vitalap | szerkesztései) |
Stma (vitalap | szerkesztései) (→yield hogyan) |
||
(egy szerkesztő 10 közbeeső változata nincs mutatva) | |||
25. sor: | 25. sor: | ||
A '''gvar''' változó a MyClass osztály szintű azaz az osztály nevével elérhető nem kell példányosítani. | A '''gvar''' változó a MyClass osztály szintű azaz az osztály nevével elérhető nem kell példányosítani. | ||
− | + | Az '''fv''' metódus csak példányon, vagy létező példánnyal hívható meg. | |
+ | |||
+ | Eddig definíciókat írtunk. Olyan mint a fv definíció, ez még magában nem fut le, csak definiálunk egy típust. | ||
+ | Az osztályokat a program futása során példányosítjuk. | ||
− | |||
<python> | <python> | ||
− | + | x = MyClass() | |
+ | # hasonloan mint mondjuk egy listát | ||
+ | l = list() | ||
+ | # vagy mas tipusokat ugyanis minden elem a python-on belül osztály lesz | ||
+ | d = dict() | ||
+ | </python> | ||
− | + | Amikor egy osztályt példányosítunk akkor a példányon elérjük az osztály definíciójában definiált változókat és függvényeket. | |
− | + | ||
− | + | ||
− | + | ||
+ | <python> | ||
+ | x = MyClass() | ||
+ | x.fv() | ||
+ | MyClass.fv(x) # a két fv. hívás megegyezik | ||
</python> | </python> | ||
48. sor: | 56. sor: | ||
A python osztályok alapvetően nem valók absztrakt definiálásra, ebben van az egyszerűsége. | A python osztályok alapvetően nem valók absztrakt definiálásra, ebben van az egyszerűsége. | ||
+ | |||
+ | Ha a osztály definíciójában használunk változókat, akkor azokat látják a létrehozott példányok is, de csak addig míg felül nem írják... | ||
=== öröklés === | === öröklés === | ||
60. sor: | 70. sor: | ||
</python> | </python> | ||
− | Alapvetően minden osztály az '''object''' alosztálya. Az alosztály örökli az ős minden elemét. | + | Alapvetően minden osztály az '''object''' alosztálya. Az alosztály örökli az ős minden elemét. Így már létező működést tudunk az új típus (osztály) - ra tenni. Ezzel újrahasznosítani a már létező kódot. |
+ | Pythonon belül egyszerre több osztálytól is leszármazhatunk. | ||
+ | |||
+ | <python> | ||
+ | class A(B, C): | ||
+ | pass | ||
+ | </python> | ||
+ | |||
+ | Itt az A osztály a B és a C -től is leszármazik. | ||
+ | |||
+ | Pythonon belül minden publikus változó, azaz ha én látom az osztály példányát akkor elérek belőle mindent. Ezért úgymond kitaláltak egy konvenciót, amit illik betartani: | ||
Megegyezés szerint. | Megegyezés szerint. | ||
− | * '''_elem''' - fél privát | + | * '''_elem''' - fél privát (csak kritikus esetben írjuk direkt) |
− | * '''__elem''' - privát | + | * '''__elem''' - privát (soha ne írjuk felül) |
− | '''isinstance''' - lehet vizsgálni | + | '''isinstance''' - lehet vizsgálni változóról, hogy milyen példány. |
<python> | <python> | ||
>>> isinstance(object, int) | >>> isinstance(object, int) | ||
84. sor: | 104. sor: | ||
</python> | </python> | ||
− | + | === konstruktor, operátorok === | |
Az '''__init__''' metódus az osztály konstruktorát reprezentálja. Amikor létrehozunk egy példányt az osztályból ez a függvény hívódik meg. | Az '''__init__''' metódus az osztály konstruktorát reprezentálja. Amikor létrehozunk egy példányt az osztályból ez a függvény hívódik meg. | ||
102. sor: | 122. sor: | ||
További operátorok: | További operátorok: | ||
− | __iter__, __mul__, __add__, __getitem__, __setitem__, __getattr__, __call__, __del__, __len__, __cmp__, | + | * iterátor lekérése (iter fv.) |
+ | __iter__, | ||
+ | * +, -, /, stb. operátorok | ||
+ | __mul__, __add__, | ||
+ | * lista elem lekérés, slice ([], [:]) | ||
+ | __getitem__, __setitem__, __getslice__ | ||
+ | * attribútum lekérése (.) | ||
+ | __getattr__, | ||
+ | * hívás (()) | ||
+ | __call__, | ||
+ | * törlése (del fv.) | ||
+ | __del__, | ||
+ | * hossza (len fv.) | ||
+ | __len__, | ||
+ | * összehasonlító operátorok (==, <, <=, >, >=, !=) | ||
+ | __eq__, __lt__, __le__, __gt__, __ge_, __ne__ | ||
+ | * stb | ||
+ | __cmp__, | ||
+ | |||
+ | [http://docs.python.org/library/operator.html#mapping-operators-to-functions syntax] | ||
+ | |||
+ | === super() függvény === | ||
+ | a super fv egy típust vár paraméterként és visszaad egy "proxy"-t amin keresztül elérjük az ős függvényeit. | ||
+ | A proxy-n az operátorok nem használhatók! | ||
+ | |||
+ | super(<type>) - type ősének közvetítőjét adja vissza | ||
+ | super(<type>, <obj>) - type ősének közvetítőjét adja vissza ha az obj type típusú | ||
+ | super(<type1>, <type2>) - az type1 type2 ősének közvetítőjét adja vissza (többes öröklés esetén) | ||
+ | |||
+ | <python> | ||
+ | class A(object): | ||
+ | def __init__(self, x): | ||
+ | self.hey = x * x | ||
+ | |||
+ | class B(A): | ||
+ | def __init__(self, x, y): | ||
+ | self.zed = y / x | ||
+ | super(B, self).__init__(x) | ||
+ | |||
+ | print B | ||
+ | a = A(5) | ||
+ | print a.hey | ||
+ | b = B(5, 30) | ||
+ | print b.zed, b.hey | ||
+ | </python> | ||
+ | |||
+ | [http://docs.python.org/library/functions.html#super super függvény leírása] | ||
+ | |||
+ | == Kivételek == | ||
+ | A kivétel olyan nyelvi elem, ami a keletkezésénél megszakítja a program futását, majd amíg nincs lekezelve mozog a program kezdeti blokkjáig, ahol az interpreter elnyeli és kilép a program futtatásából. | ||
+ | |||
+ | Ha a kivétel valahol le van kezelve, és a lekezelés során nem lépünk ki a programból, akkor a program a lekezelő blokk után fogja folytatni a futását. | ||
+ | |||
+ | Kivétel keletkezik ha nullával próbálunk osztani, ha a behúzás a program során nem egységes, ill. ha egy fájlt nem tudunk megnyitni olvasásra... | ||
+ | |||
+ | == kivételek kezelése == | ||
+ | A kivételekre lehet azért számítani, és ha kell akkor megfelelően lekezelni a következő módon: | ||
− | |||
<python> | <python> | ||
try: | try: | ||
164. sor: | 239. sor: | ||
=== with értelmezése === | === with értelmezése === | ||
+ | A '''with''' kulcsszó alapvetően erőforrások lefoglalására majd a with blokk elhagyása után azok felszabadítására használható. Bővebb értelemben pedig bármire, amit a blokk előtt és után mindig le szeretnénk futtatni. | ||
+ | |||
+ | <python> | ||
+ | with obj as var: | ||
+ | ...code block | ||
+ | </python> | ||
+ | |||
Egyenértékű kód: | Egyenértékű kód: | ||
+ | |||
<python> | <python> | ||
__enter__() | __enter__() | ||
177. sor: | 260. sor: | ||
doSth() | doSth() | ||
</python> | </python> | ||
+ | |||
+ | A mélyére ásva a with akkor használható, ha az objektumnak amin értelmezett (obj) definiált az '''__enter__''' és a '''__exit__''' operátor. Ugyanis ahogy látszik az egyenértékű kódon ezeket hajtja végre a blokk elején és végén. Az as után álló var pedig az __enter__ visszatérési értéke lesz, amit felhasználhatunk a blokkon belül. | ||
[http://effbot.org/zone/python-with-statement.htm egy magyarázat] | [http://effbot.org/zone/python-with-statement.htm egy magyarázat] | ||
− | + | == iterátorok == | |
iterátorok segítségével tudjuk a sorozatokat bejárni. Az '''iter''' fv képes visszaadni a sorozat iterátorát amin a '''next''' fv segítségével lehet lépegetni. | iterátorok segítségével tudjuk a sorozatokat bejárni. Az '''iter''' fv képes visszaadni a sorozat iterátorát amin a '''next''' fv segítségével lehet lépegetni. | ||
203. sor: | 288. sor: | ||
</python> | </python> | ||
− | + | == yield hogyan == | |
Memória barát funkcionális program elem, generátor | Memória barát funkcionális program elem, generátor | ||
+ | |||
+ | === generátor === | ||
+ | |||
+ | a generátor egy olyan különleges iterátor, aminek az elemei nem foglalnak helyet a memóriában, hanem lépésről lépésre "generálódik". A generátor elemein csak egyszer tudsz végig menni. [http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained egy magyarázat] | ||
+ | |||
+ | ==== generátor kifejezés ==== | ||
+ | <python> | ||
+ | (i*i for i in range(1,11)) | ||
+ | </python> | ||
+ | |||
+ | Ez a kód egy generátort eredményez, ami 1 - 10 négyzetét adja vissza elemeiként. [http://www.python.org/dev/peps/pep-0289/ bővebb leírás] | ||
<python> | <python> | ||
219. sor: | 315. sor: | ||
g | g | ||
</python> | </python> | ||
− | |||
− | |||
− | |||
− |
A lap jelenlegi, 2012. szeptember 5., 00:38-kori változata
Tartalomjegyzék |
Osztályok és kivételek
Osztályok
Az osztályokat alapvetően egységbezárásra használják. Ami által a program tagolhatósága és újrahasznosítása nő.
Osztályok változókból és metódusokból állnak.
class MyClass: pass
Az előbbi kód egy alap gyűjtő osztályt reprezentál.
class MyClass: gvar = 667 def fv(self): pass
A gvar változó a MyClass osztály szintű azaz az osztály nevével elérhető nem kell példányosítani. Az fv metódus csak példányon, vagy létező példánnyal hívható meg.
Eddig definíciókat írtunk. Olyan mint a fv definíció, ez még magában nem fut le, csak definiálunk egy típust. Az osztályokat a program futása során példányosítjuk.
x = MyClass() # hasonloan mint mondjuk egy listát l = list() # vagy mas tipusokat ugyanis minden elem a python-on belül osztály lesz d = dict()
Amikor egy osztályt példányosítunk akkor a példányon elérjük az osztály definíciójában definiált változókat és függvényeket.
x = MyClass() x.fv() MyClass.fv(x) # a két fv. hívás megegyezik
Az osztály elemeit nem szükséges a definíció során megadni. Utólag is hozzáadhatjuk.
x.count = 1 x.count += 1 # es szinten torolheto is del(x.count)
A python osztályok alapvetően nem valók absztrakt definiálásra, ebben van az egyszerűsége.
Ha a osztály definíciójában használunk változókat, akkor azokat látják a létrehozott példányok is, de csak addig míg felül nem írják...
öröklés
>>> class A(object): ... pass ... >>> a = A() >>> a.t = 5 >>> a.t 5
Alapvetően minden osztály az object alosztálya. Az alosztály örökli az ős minden elemét. Így már létező működést tudunk az új típus (osztály) - ra tenni. Ezzel újrahasznosítani a már létező kódot.
Pythonon belül egyszerre több osztálytól is leszármazhatunk.
class A(B, C): pass
Itt az A osztály a B és a C -től is leszármazik.
Pythonon belül minden publikus változó, azaz ha én látom az osztály példányát akkor elérek belőle mindent. Ezért úgymond kitaláltak egy konvenciót, amit illik betartani: Megegyezés szerint.
- _elem - fél privát (csak kritikus esetben írjuk direkt)
- __elem - privát (soha ne írjuk felül)
isinstance - lehet vizsgálni változóról, hogy milyen példány.
>>> isinstance(object, int) False >>> isinstance(int, object) True >>> isinstance(x, object) True
issubclass - a leszármazást lehet vele vizsgálni hasonló képen
Több osztályt is megadhatunk leszármazás során
class A(B,C): pass
konstruktor, operátorok
Az __init__ metódus az osztály konstruktorát reprezentálja. Amikor létrehozunk egy példányt az osztályból ez a függvény hívódik meg.
A __repr__ - a repr() által visszaadott elemet definiálhatjuk, hasonló képen a __str__ a str() fv-vel.
class Position3D: def __init__(self,x,y,z): self.pos = (x,y,z) def get_y(): return self.pos[1] def __repr__(self): return 'This position is in:\n\tx: {0:d}, y: {1:d}, z:{2:d}'.format(self.pos[0],self.pos[1],self.pos[2])
További operátorok:
- iterátor lekérése (iter fv.)
__iter__,
- +, -, /, stb. operátorok
__mul__, __add__,
- lista elem lekérés, slice ([], [:])
__getitem__, __setitem__, __getslice__
- attribútum lekérése (.)
__getattr__,
- hívás (())
__call__,
- törlése (del fv.)
__del__,
- hossza (len fv.)
__len__,
- összehasonlító operátorok (==, <, <=, >, >=, !=)
__eq__, __lt__, __le__, __gt__, __ge_, __ne__
- stb
__cmp__,
super() függvény
a super fv egy típust vár paraméterként és visszaad egy "proxy"-t amin keresztül elérjük az ős függvényeit. A proxy-n az operátorok nem használhatók!
super(<type>) - type ősének közvetítőjét adja vissza super(<type>, <obj>) - type ősének közvetítőjét adja vissza ha az obj type típusú super(<type1>, <type2>) - az type1 type2 ősének közvetítőjét adja vissza (többes öröklés esetén)
class A(object): def __init__(self, x): self.hey = x * x class B(A): def __init__(self, x, y): self.zed = y / x super(B, self).__init__(x) print B a = A(5) print a.hey b = B(5, 30) print b.zed, b.hey
Kivételek
A kivétel olyan nyelvi elem, ami a keletkezésénél megszakítja a program futását, majd amíg nincs lekezelve mozog a program kezdeti blokkjáig, ahol az interpreter elnyeli és kilép a program futtatásából.
Ha a kivétel valahol le van kezelve, és a lekezelés során nem lépünk ki a programból, akkor a program a lekezelő blokk után fogja folytatni a futását.
Kivétel keletkezik ha nullával próbálunk osztani, ha a behúzás a program során nem egységes, ill. ha egy fájlt nem tudunk megnyitni olvasásra...
kivételek kezelése
A kivételekre lehet azért számítani, és ha kell akkor megfelelően lekezelni a következő módon:
try: ... except <exp> as <v>: ... else: ... finally: ...
Kivételek elemei:
>>> try: ... raise Exception('spam', 'eggs') ... except Exception as inst: ... print type(inst) # the exception instance ... print inst.args # arguments stored in .args ... print inst # __str__ allows args to printed directly ... x, y = inst # __getitem__ allows args to be unpacked directly ... print 'x =', x ... print 'y =', y ... <type 'exceptions.Exception'> ('spam', 'eggs') ('spam', 'eggs') x = spam y = eggs
A kivételek is osztályok, és azok is leszármaztathatók.
>>> class B(): ... pass ... >>> class C(B): ... pass ... >>> class D(C): ... pass ... >>> for c in [B,C,D]: ... try: ... raise c() ... except D: ... print "d" ... except C: ... print 'c' ... except B: ... print 'b' ... b c d
with értelmezése
A with kulcsszó alapvetően erőforrások lefoglalására majd a with blokk elhagyása után azok felszabadítására használható. Bővebb értelemben pedig bármire, amit a blokk előtt és után mindig le szeretnénk futtatni.
with obj as var: ...code block
Egyenértékű kód:
__enter__() try: doSth() finally: __exit__() # azaz with <valami> as <valt>: doSth()
A mélyére ásva a with akkor használható, ha az objektumnak amin értelmezett (obj) definiált az __enter__ és a __exit__ operátor. Ugyanis ahogy látszik az egyenértékű kódon ezeket hajtja végre a blokk elején és végén. Az as után álló var pedig az __enter__ visszatérési értéke lesz, amit felhasználhatunk a blokkon belül.
iterátorok
iterátorok segítségével tudjuk a sorozatokat bejárni. Az iter fv képes visszaadni a sorozat iterátorát amin a next fv segítségével lehet lépegetni.
>>> t='alma' >>> i=iter(t) >>> i <iterator object at 0xb73c4dec> >>> i.next() 'a' >>> i.next() 'l' >>> i.next() 'm' >>> i.next() 'a' >>> i.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
yield hogyan
Memória barát funkcionális program elem, generátor
generátor
a generátor egy olyan különleges iterátor, aminek az elemei nem foglalnak helyet a memóriában, hanem lépésről lépésre "generálódik". A generátor elemein csak egyszer tudsz végig menni. egy magyarázat
generátor kifejezés
(i*i for i in range(1,11))
Ez a kód egy generátort eredményez, ami 1 - 10 négyzetét adja vissza elemeiként. bővebb leírás
def reverse(data): for index in range(len(data)-1, -1, -1): yield data[index] >>> for char in reverse('golf'): ... print char ... f l o g