# Generátorok
####################################################
# Egy generátor értékeket "generál" amikor kérik, a helyett, hogy előre eltárolná őket.
# A következő metódus (ez még NEM egy generátor) megduplázza a kapott iterable elemeit,
# és eltárolja őket. Nagy méretű iterable esetén ez nagyon sok helyet foglalhat!
def double_numbers(iterable):
double_arr = []
for i in iterable:
double_arr.append(i + i)
return double_arr
# A következő kód futtatásakor az összes szám kétszeresét kiszámítanánk, és visszaadnánk
# ezt a nagy listát a ciklus vezérléséhez.
for value in double_numbers(range(1000000)): # `test_non_generator`
print value
if value > 5:
break
# Használjunk inkább egy generátort, ami "legenerálja" a soron következő elemet,
# amikor azt kérik tőle
def double_numbers_generator(iterable):
for i in iterable:
yield i + i
# A lenti kód mindig csak a soron következő számot generálja a logikai vizsgálat előtt.
# Így amikor az érték eléri a > 5 határt, megszakítjuk a ciklust, és a lista számainak
# nagy részénél megspóroltuk a duplázás műveletet (ez sokkal gyorsabb így!).
for value in double_numbers_generator(xrange(1000000)): # `test_generator`
print value
if value > 5:
break
# Feltűnt, hogy a `test_non_generator` esetén `range`, a `test_generator` esetén
# pedig `xrange` volt a segédfüggvény neve? Ahogy `double_numbers_generator` a
# generátor változata a `double_numbers` függvénynek, úgy az `xrange` a `range`
# generátor megfelelője, csak akkor generálja le a következő számot, amikor kérjük
# - esetünkben a ciklus következő iterációjakor
# A lista képzéshez hasonlóan generátor képzőket is használhatunk
# ("generator comprehensions").
values = (-x for x in [1, 2, 3, 4, 5])
for x in values:
print(x) # kimenet: -1 -2 -3 -4 -5
# Egy generátor összes generált elemét listaként is elkérhetjük:
values = (-x for x in [1, 2, 3, 4, 5])
gen_to_list = list(values)
print(gen_to_list) # => [-1, -2, -3, -4, -5]
# Dekorátorok
# A dekorátor egy magasabb rendű függvény, aminek bemenete és kimenete is egy függvény.
# A lenti egyszerű példában az add_apples dekorátor a dekorált get_fruits függvény
# kimenetébe beszúrja az 'Apple' elemet.
def add_apples(func):
def get_fruits():
fruits = func()
fruits.append('Apple')
return fruits
return get_fruits
@add_apples
def get_fruits():
return ['Banana', 'Mango', 'Orange']
# A kimenet tartalmazza az 'Apple' elemet:
# Banana, Mango, Orange, Apple
print ', '.join(get_fruits())
# Ebben a példában a beg dekorátorral látjuk el a say függvényt.
# Beg meghívja say-t. Ha a say_please paraméter igaz, akkor
# megváltoztatja az eredmény mondatot.
from functools import wraps
def beg(target_function):
@wraps(target_function)
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
if say_please:
return "{} {}".format(msg, "Please! I am poor :(")
return msg
return wrapper
@beg
def say(say_please=False):
msg = "Can you buy me a beer?"
return msg, say_please
print say() # Can you buy me a beer?
print say(say_please=True) # Can you buy me a beer? Please! I am poor :(
Megjegyzések
Megjegyzés küldése