Protokół iteratora
Poznaj __iter__ i __next__
Protokół iteratora to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.
Czym jest iteracja?
Za każdym razem, gdy używa się pętli for dla listy, napisu lub słownika, Python korzysta w tle z protokołu iteratora.
Obiekt, po którym można iterować, jest nazywany obiektem iterowalnym. Element, który faktycznie dostarcza wartości pojedynczo, jest nazywany iteratorem.
for ch in 'abc':
print(ch)iter() i next()
Iteracją sterują dwie funkcje wbudowane:
iter(obj)prosi obiekt iterowalny o jego iterator;next(it)prosi iterator o następną wartość.
Gdy nie ma już żadnych wartości, next() zgłasza wyjątek StopIteration.
it = iter([10, 20, 30])
print(next(it))
print(next(it))
print(next(it))StopIteration
Jedno wywołanie next() za dużo powoduje zgłoszenie wyjątku StopIteration. Pętla for automatycznie go przechwytuje i poprawnie się kończy.
it = iter([1])
print(next(it))
try:
next(it)
except StopIteration:
print('No more items')Dwie metody dunder
Aby utworzyć własny iterator, należy zaimplementować dwie metody:
__iter__zwraca sam obiekt iteratora;__next__zwraca następną wartość lub zgłasza wyjątekStopIteration.
class Count:
def __init__(self, n):
self.i = 0
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.i >= self.n:
raise StopIteration
self.i += 1
return self.i
for x in Count(3):
print(x)Obiekt iterowalny a iterator
Obiekt iterowalny potrzebuje tylko __iter__. Iterator potrzebuje zarówno __iter__, jak i __next__.
Listy są obiektami iterowalnymi, ale nie iteratorami: każde wywołanie iter() zwraca nowy iterator.
nums = [1, 2, 3]
print(iter(nums) is iter(nums))
it = iter(nums)
print(it is iter(it))Iterator można wyczerpać tylko raz
Iterator można wykorzystać tylko raz. Po dotarciu do końca pozostaje pusty. Aby iterować ponownie, należy utworzyć nowy iterator.
it = iter([1, 2])
print(list(it))
print(list(it))Iterator podobny do range
Utwórzmy własny iterator działający jak prosty licznik. Zwróćmy uwagę, że stan jest przechowywany w instancji.
class EvenUpTo:
def __init__(self, limit):
self.cur = 0
self.limit = limit
def __iter__(self):
return self
def __next__(self):
if self.cur > self.limit:
raise StopIteration
value = self.cur
self.cur += 2
return value
print(list(EvenUpTo(8)))Rozdzielanie obiektu iterowalnego i iteratora
Przejrzystszy projekt rozdziela kontener i iterator, dzięki czemu po kontenerze można iterować wiele razy.
class Bag:
def __init__(self, items):
self.items = items
def __iter__(self):
return BagIterator(self.items)
class BagIterator:
def __init__(self, items):
self.items = items
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i >= len(self.items):
raise StopIteration
v = self.items[self.i]
self.i += 1
return v
b = Bag(['x', 'y'])
print(list(b))
print(list(b))Używanie next() z wartością domyślną
next(it, default) zwraca wartość domyślną zamiast zgłaszać StopIteration, gdy iterator jest pusty. To przydatne podczas bezpiecznego sprawdzania następnej wartości.
it = iter([42])
print(next(it, 'done'))
print(next(it, 'done'))Iteratory oszczędzają pamięć
Iteratory zwracają po jednym elemencie naraz, więc nie muszą przechowywać w pamięci całej sekwencji. Dzięki temu można ich używać z ogromnymi, a nawet nieskończonymi strumieniami.
class Naturals:
def __init__(self):
self.n = 0
def __iter__(self):
return self
def __next__(self):
self.n += 1
return self.n
it = iter(Naturals())
print(next(it), next(it), next(it))Wbudowane funkcje zużywające iteratory
Wiele wbudowanych funkcji akceptuje dowolny iterator: sum, max, min, sorted, list, tuple. Pobierają wartości aż do wystąpienia StopIteration.
class Count:
def __init__(self, n):
self.i = 0
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.i >= self.n:
raise StopIteration
self.i += 1
return self.i
print(sum(Count(5)))
print(max(Count(5)))Szybkie sprawdzenie
Sprawdź swoją znajomość protokołu iteratora.
Podsumowanie
Poznałeś(-aś) protokół iteratora:
iter()pobiera iterator, anext()pobiera wartości.StopIterationsygnalizuje koniec, aforobsługuje ten wyjątek.- Niestandardowe iteratory implementują metody
__iter__i__next__. - Iteratorów można użyć tylko raz i są oszczędne pamięciowo.
W następnym kroku pozwolisz Pythonowi tworzyć iteratory za pomocą yield.
Często zadawane pytania
Czy lekcja „Protokół iteratora” jest bezpłatna?
Tak — pełny tekst „Protokół iteratora” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Protokół iteratora”?
Poznaj __iter__ i __next__ Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Python Academy?
Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Protokół iteratora”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?
Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Protokół iteratora
- Funkcje generatorów
- Wyrażenia generatorowe
- yield from i delegowanie