Что такое метод next в итераторах и как он реализуется
Что проверяют
Понимаете ли вы протокол итерации, а не только цикл for. Для инженера данных это прикладной вопрос: потоковая обработка держится на том, что элементы тянутся по одному и весь набор в памяти не лежит.
Как отвечать
Разведите понятия. Итерируемое отдаёт итератор по вызову iter, итератор отдаёт следующий элемент и исчерпывается навсегда. В Python next это встроенная функция, она вызывает метод __next__ объекта; когда элементы кончились, метод возбуждает StopIteration, и цикл for ловит его молча.
class Batches:
def __iter__(self):
return self
def __next__(self):
if self.i >= len(self.rows):
raise StopIteration
chunk = self.rows[self.i:self.i + self.size]
self.i += self.size
return chunkСкажите про вариант с умолчанием: next(it, None) вернёт подставленное значение вместо исключения, это удобно, когда надо заглянуть в первый элемент потока и решить, что делать дальше. Полезно назвать и двухаргументную форму iter: она тянет значения из функции, пока та не вернёт сторожевое, и так читают файл или сокет кусками фиксированного размера.
Добавьте, что на практике такой класс почти всегда пишут генератором: yield хранит состояние между вызовами без ручного индекса, а память при этом занимает один элемент, а не весь набор.
Где спотыкаются
Называют next методом объекта. Метод называется __next__, а next это функция; вместе с этим путают роли __iter__ и __next__ и пишут класс, у которого __iter__ возвращает не итератор.
Считают итератор списком. По нему проходят один раз: после исчерпания второй цикл for отработает вхолостую, и это регулярная причина пустых выгрузок, когда один и тот же курсор читают дважды.
Гасят StopIteration широким блоком except. Внутри генератора это исключение вообще нельзя выпускать наружу: интерпретатор превращает его в ошибку времени выполнения, чтобы молча оборванная итерация не выглядела нормальным завершением.