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)
Brak komentarzy...