Informatika2-2014/teszt
(A lap tartalmának cseréje erre: \b(?=[MDCLXVI])M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b [1-9](\d{0,2}( \d{3})+|\d*) \b(0|[1-9](\d{0,2}(,\d{3})+|\d*))\b ([0-9A-Fa-f]{3}){…) |
|||
(egy szerkesztő 39 közbeeső változata nincs mutatva) | |||
1. sor: | 1. sor: | ||
+ | === Dekorátor === | ||
− | + | Jó leírások: [[http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/]], [[http://www.artima.com/weblogs/viewpost.jsp?thread=240808]] | |
− | + | A '''dekorátorok''' módosítják függvények vagy osztályok kódját! | |
− | + | ==== Scope (hatókör), névtér ==== | |
− | + | Minden új függvény fölépíti saját névterét, egy szótár formájában. Íme a globális és egy lokális névtér: | |
+ | <python> | ||
+ | >>> x = 2 | ||
+ | >>> print globals() | ||
+ | {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 2, '__doc__': None, '__package__': None} | ||
+ | >>> def fn(): | ||
+ | ... y = 3 | ||
+ | ... print locals() | ||
+ | ... | ||
+ | >>> fn() | ||
+ | {'y': 3} | ||
+ | </python> | ||
− | + | Ha egy név lokálisan nem lett létrehozva, a tartalmazó névterekben keresi egyre kijjebb haladva (itt az x nem lett lokálisan létrehozva, de elérhető): | |
+ | |||
+ | <python> | ||
+ | >>> def fn(): | ||
+ | ... y = 3 | ||
+ | ... print "x, y:", x, y | ||
+ | ... print locals() | ||
+ | ... | ||
+ | >>> fn() | ||
+ | x, y: 2 3 | ||
+ | {'y': 3} | ||
+ | </python> | ||
+ | |||
+ | Kérdés: Mi történik az alábbi kód hatására? magyarázzuk meg, mi történik: | ||
+ | |||
+ | <python> | ||
+ | >>> def fn(): | ||
+ | ... y = 3 | ||
+ | ... print "x, y:", x, y | ||
+ | ... x = 5 | ||
+ | ... print locals() | ||
+ | ... | ||
+ | >>> fn() | ||
+ | </python> | ||
+ | |||
+ | És mi történik, ha a 3. és 4. sort fölcseréljük? | ||
+ | |||
+ | A névtér törlődik a függvény lefutása után, magasabb szinten az alacsonyabb szintű névterek nem érhetők el: | ||
+ | |||
+ | <python> | ||
+ | >>> def fn(): | ||
+ | ... z = 1 | ||
+ | ... | ||
+ | >>> print z | ||
+ | Traceback (most recent call last): | ||
+ | File "<stdin>", line 1, in <module> | ||
+ | NameError: name 'z' is not defined | ||
+ | </python> | ||
+ | |||
+ | A '''függvény lezárása''' a Pythonnak azt a képességét jelenti, hogy a nem globális névtérben definiált függvény '''emlékszik''' a definiálás pillanatában érvényes bennfoglaló névterekre: | ||
+ | |||
+ | <python> | ||
+ | >>> def kulso(x): | ||
+ | ... def belso(): | ||
+ | ... print x | ||
+ | ... return belso | ||
+ | ... | ||
+ | >>> f1 = kulso(3) | ||
+ | >>> f2 = kulso(5) | ||
+ | >>> | ||
+ | >>> f1() | ||
+ | 3 | ||
+ | >>> f2() | ||
+ | 5 | ||
+ | </python> | ||
+ | |||
+ | ==== Dekorálunk ==== | ||
+ | |||
+ | A külső függvény az argumentumában átadott függvény eredményét duplázza, és ezt a duplázó függvényt adja vissza. Ezzel '''dekorálunk''' két különböző függvényt! | ||
+ | |||
+ | <python> | ||
+ | >>> def kulso(fn): | ||
+ | ... def belso(*args): | ||
+ | ... print "belül vagyunk" | ||
+ | ... return 2*fn(*args) | ||
+ | ... return belso | ||
+ | ... | ||
+ | >>> dekoralt = kulso(fv) | ||
+ | >>> dekoralt(5) | ||
+ | belül vagyunk | ||
+ | 10 | ||
+ | >>> def fadd(a, b): | ||
+ | ... return a + b | ||
+ | ... | ||
+ | >>> dekoralt = kulso(fadd) | ||
+ | >>> dekoralt(4, 5) | ||
+ | belül vagyunk | ||
+ | 18 | ||
+ | </python> | ||
+ | |||
+ | A <code>fv = kulso(fv)</code> rövidítése a <code>@kulso</code> a fv függvénydefiníció elé írásával: | ||
+ | |||
+ | <python> | ||
+ | >>> @kulso | ||
+ | ... def fmul(a, b): | ||
+ | ... return a * b | ||
+ | ... | ||
+ | >>> fmul(3, 5) | ||
+ | belül vagyunk | ||
+ | 30 | ||
+ | </python> | ||
+ | |||
+ | |||
+ | Dekorátor lehet olyan osztály is, mely '''meghívható''', azaz amelyben létezik <code>__call__</code> függvény: | ||
+ | |||
+ | <python> | ||
+ | >>> class Dekorator(object): | ||
+ | ... def __init__(self, f): | ||
+ | ... print "Dekorátor konstruktor" | ||
+ | ... print "meghívjuk a fv-t:", f() | ||
+ | ... def __call__(self): | ||
+ | ... print "Dekorátor meghívása" | ||
+ | ... | ||
+ | >>> @Dekorator | ||
+ | ... def fn(): | ||
+ | ... print "az fn meghívása" | ||
+ | ... | ||
+ | Dekorátor konstruktor | ||
+ | meghívjuk a fv-t: az fn meghívása | ||
+ | None | ||
+ | >>> fn() | ||
+ | Dekorátor meghívása | ||
+ | </python> |
A lap jelenlegi, 2014. március 26., 10:29-kori változata
Dekorátor
A dekorátorok módosítják függvények vagy osztályok kódját!
Scope (hatókör), névtér
Minden új függvény fölépíti saját névterét, egy szótár formájában. Íme a globális és egy lokális névtér:
>>> x = 2 >>> print globals() {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 2, '__doc__': None, '__package__': None} >>> def fn(): ... y = 3 ... print locals() ... >>> fn() {'y': 3}
Ha egy név lokálisan nem lett létrehozva, a tartalmazó névterekben keresi egyre kijjebb haladva (itt az x nem lett lokálisan létrehozva, de elérhető):
>>> def fn(): ... y = 3 ... print "x, y:", x, y ... print locals() ... >>> fn() x, y: 2 3 {'y': 3}
Kérdés: Mi történik az alábbi kód hatására? magyarázzuk meg, mi történik:
>>> def fn(): ... y = 3 ... print "x, y:", x, y ... x = 5 ... print locals() ... >>> fn()
És mi történik, ha a 3. és 4. sort fölcseréljük?
A névtér törlődik a függvény lefutása után, magasabb szinten az alacsonyabb szintű névterek nem érhetők el:
>>> def fn(): ... z = 1 ... >>> print z Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'z' is not defined
A függvény lezárása a Pythonnak azt a képességét jelenti, hogy a nem globális névtérben definiált függvény emlékszik a definiálás pillanatában érvényes bennfoglaló névterekre:
>>> def kulso(x): ... def belso(): ... print x ... return belso ... >>> f1 = kulso(3) >>> f2 = kulso(5) >>> >>> f1() 3 >>> f2() 5
Dekorálunk
A külső függvény az argumentumában átadott függvény eredményét duplázza, és ezt a duplázó függvényt adja vissza. Ezzel dekorálunk két különböző függvényt!
>>> def kulso(fn): ... def belso(*args): ... print "belül vagyunk" ... return 2*fn(*args) ... return belso ... >>> dekoralt = kulso(fv) >>> dekoralt(5) belül vagyunk 10 >>> def fadd(a, b): ... return a + b ... >>> dekoralt = kulso(fadd) >>> dekoralt(4, 5) belül vagyunk 18
A fv = kulso(fv)
rövidítése a @kulso
a fv függvénydefiníció elé írásával:
>>> @kulso ... def fmul(a, b): ... return a * b ... >>> fmul(3, 5) belül vagyunk 30
Dekorátor lehet olyan osztály is, mely meghívható, azaz amelyben létezik __call__
függvény:
>>> class Dekorator(object): ... def __init__(self, f): ... print "Dekorátor konstruktor" ... print "meghívjuk a fv-t:", f() ... def __call__(self): ... print "Dekorátor meghívása" ... >>> @Dekorator ... def fn(): ... print "az fn meghívása" ... Dekorátor konstruktor meghívjuk a fv-t: az fn meghívása None >>> fn() Dekorátor meghívása