programowanieProgramista Backend

Opowiedz o działaniu iteratorów w Pythonie. Jak zaimplementować własny iterator? Jaka jest różnica między iteratorami a obiektami iterowalnymi?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

W Pythonie iteratory to obiekty, które implementują protokół iteratora: metody __iter__() i __next__(). Iteratory zarządzają swoim wewnętrznym stanem i przy każdym wywołaniu next() zwracają następny element sekwencji lub podnoszą wyjątek StopIteration na końcu.

Obiekty iterowalne to te, po których można przechodzić w pętli (na przykład listy, ciągi, słowniki). Wszystkie mają metodę __iter__(), która zwraca iterator.

Aby zaimplementować własny iterator, należy stworzyć klasę z metodami __iter__() (zwraca self) i __next__() (implementuje logikę pobierania następnego elementu):

class Counter: def __init__(self, low, high): self.current = low self.high = high def __iter__(self): return self def __next__(self): if self.current > self.high: raise StopIteration else: self.current += 1 return self.current - 1 for num in Counter(1, 3): print(num) # 1 2 3

Pytanie podchwytliwe.

Jaka jest różnica między obiektami iterowalnymi a iteratorami? Czy można iterować po iteratorze więcej niż raz?

Odpowiedź: Obiekt iterowalny implementuje tylko metodę __iter__(), która zwraca iterator. Iterator to obiekt, który ma metodę __next__(). Iterator zazwyczaj można iterować tylko raz: po osiągnięciu końca sekwencji ponowna iteracja nie jest możliwa bez utworzenia nowego iteratora.

Przykłady rzeczywistych błędów z powodu nieznajomości szczegółów tematu.


Historia

Na projekcie do analizy logów programista napisał funkcję, która przyjmowała iterator i dwukrotnie próbowała po nim przejść (for log in logs:), oczekując, że oba przejścia dadzą te same wyniki. Druga iteracja nic nie zwracała, ponieważ iterator był już "wykorzystany".


Historia

W jednym z modułów programista zwrócił z funkcji nie listę, a generator, który umożliwiał jednokrotną iterację. Przy próbie przekazania go do innej funkcji, która oczekiwała obiektu iterowalnego do wielu przejść, wystąpił nieoczekiwany błąd i pusty wynik.


Historia

W projekcie Web API programista próbował zserializować iterator bezpośrednio do JSON. Iteratory nie są listami, a konwersja nie jest możliwa bez wcześniejszego przekształcenia do listy (w przeciwnym razie serializacja zakończy się wyjątkiem).