В Python иттераторы — это объекты, которые реализуют протокол итератора: методы __iter__() и __next__(). Итераторы управляют своим внутренним состоянием и при каждом вызове next() возвращают следующий элемент последовательности или выбрасывают исключение StopIteration по окончании.
Итерируемые объекты — это те, над которыми можно проходить в цикле (например, списки, строки, словари). У всех них есть метод __iter__(), который возвращает итератор.
Чтобы реализовать собственный итератор, нужно создать класс с методами __iter__() (возвращает self) и __next__() (реализует логику получения следующего элемента):
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
В чём отличия между итерируемыми объектами и итераторами? Можно ли итерироваться по итератору более одного раза?
Ответ: Итерируемый объект реализует только метод __iter__(), который возвращает итератор. Итератор — это объект, у которого есть метод __next__(). Итератор обычно итерируется только один раз: после достижения конца последовательности повторная итерация невозможна без создания нового итератора.
История
На проекте для анализа логов разработчик написал функцию, которая принимала итератор и дважды пыталась пройти по нему (
for log in logs:), ожидая, что оба прохода дадут одинаковые результаты. Вторая итерация ничего не возвращала, потому что итератор был уже "исчерпан".
История
В одном модуле разработчик вернул из функции не список, а генератор, позволявший однократную итерацию. При попытке передать его в другую функцию, которая ожидала итерируемый объект для нескольких обходов, возникла неожиданная ошибка и пустой результат.
История
В проекте Web API разработчик попытался сериализовать итератор напрямую в JSON. Итераторы не являются списками, и преобразование невозможно без предварительного приведения к списку (иначе сериализация завершится исключением).