Ugrás a fő tartalomra

Python nyelv alapjai generátorok




# 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