Blog JSystems - uwalniamy wiedzę!

Szukaj

Iterator to obiekt pozwalający na sekwencyjny dostęp do kolejnych elementów. Aby stworzyć iterator musimy w klasie zaimplementować dwie funkcje - "__iter__()" i "__next__()". Funkcja "__iter__()" zwraca obiekt iteratora, a "__next__()" zwraca kolejne elementy. "__next__()" wywołuje też wyjątek "StopIteration" kiedy nie ma już więcej elementów do oddania. Przeanalizujmy poniższy przykład:


class IncrementIterator:

    def __init__(self, n):
        self.n = n
        self.i = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.n == self.i:
            raise StopIteration
        self.i += 1
        return self.i

for e in IncrementIterator(10):
    print(e)


Przesłaniam metodę "__init__" w celu przekazania do obiektu maksymalnej wartości do której chcemy iterować. Metoda "__iter__" musi zwracać obiekt iterowalny, tak więc w tym przypadku zwracam "siebie" czyli obiekt w którym się znajduję. Metoda "__next__" powiększa o 1 i zwraca wewnątrzobiektową zmienną. Zwróć uwagę że w związku z taką konstrukcją obiekt "pamięta" jaką wartość oddał ostatnio. Przy każdym kolejnym wywołaniu "__next__" jest też sprawdzane czy nie dotarliśmy do maksimum do którego mieliśmy iterować, a jeśli tak to wywołujemy wyjątek "StopIteration". Pod deklaracją klasy iterujemy po naszym iteratorze. W wyniku działania dostajemy na konsoli kolejne liczby od 1 do 10. Jeśli raz przeiterujemy po naszym iteratorze, to nie ma możliwości jej "zresetowania". Aby zacząć liczyć od nowa, musimy stworzyć nowy obiekt.


Poprzedni przykład zakładał limit ilości zwracanych elementów. W Pythonie możemy tworzyć również nieskończone iteratory. Poniżej przykład:


class NieskonczonyIterator:
    x=0
    def __iter__(self):
        return self
    def __next__(self):
        self.x+=1
        return self.x

ni=NieskonczonyIterator()
for i in range(10):
    print(  next(ni)  )


Tym razem nie mamy metody "__init__" któraby ustawiała jakiś maksymalny próg zwracanych wartości. W metodzie "__next__" nie rzucam w związku z tym wyjątkiem "StopIteration". Mój iterator będzie więc podawał kolejne liczby bez ograniczeń. Pod przykładem iteratora prezentuję przykład pobierania wartości z takiego iteratora. Tym razem muszę posłużyć się funkcją "next" od obiektu iteratora by pobierać kolejne wartości.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...