Что такое итератор
Итератор (iterator) — это объект, который представляет поток данных и возвращает элементы по одному за раз. Повторный вызов метода __next__() (или встроенной функции next()) возвращает следующий элемент потока, а когда элементы заканчиваются, выбрасывается исключение StopIteration. После этого итератор считается исчерпанным, и все последующие вызовы __next__() снова генерируют StopIteration. Итератор также обязан иметь метод __iter__, который возвращает сам объект итератора, поэтому любой итератор является итерируемым объектом и может использоваться в конструкциях, ожидающих итерируемые объекты, например в цикле for.
Как это работает
Итератор реализует два ключевых метода:
__next__()— возвращает следующий элемент последовательности. Если элементов больше нет, выбрасываетStopIteration.__iter__()— возвращаетself. Это делает итератор итерируемым, позволяя использовать его вforи других местах, где ожидается итерируемый объект.
В Python итераторы формально определяются абстрактным классом collections.abc.Iterator, который наследуется от Iterable. Класс Iterator требует реализации __next__ и предоставляет __iter__ по умолчанию. Также через __subclasshook__ проверяется наличие обоих методов у класса, что позволяет использовать isinstance(obj, Iterator) для проверки.
Пример
Создадим простой итератор, который возвращает квадраты чисел от 0 до n:
class SquaresIterator:
def __init__(self, n):
self.n = n
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i >= self.n:
raise StopIteration
result = self.i ** 2
self.i += 1
return result
# Использование
squares = SquaresIterator(5)
for x in squares:
print(x) # Выведет 0, 1, 4, 9, 16Здесь __next__ возвращает квадрат текущего индекса и увеличивает его. Когда индекс достигает n, выбрасывается StopIteration, сигнализируя о конце итерации.
Подводные камни
- Исчерпание: итератор можно использовать только один раз. После того как он выбросил
StopIteration, он становится бесполезным. Чтобы пройтись по данным снова, нужно создать новый итератор. - Итератор и итерируемый объект: не путайте эти понятия. Итерируемый объект (например, список) имеет метод
__iter__, который возвращает итератор. Сам список не является итератором, так как у него нет__next__. Итератор же всегда является итерируемым. - Бесконечные итераторы: итератор может не иметь конца (например,
itertools.count). В таких случаях нужно явно ограничивать количество итераций, иначе циклforбудет бесконечным. - Реализация
__iter__: если вы пишете свой класс-итератор, обязательно возвращайтеselfиз__iter__. Если вернуть другой объект, это может привести к неожиданному поведению.
Когда использовать
Итераторы лежат в основе многих конструкций Python: циклы for, генераторы, функции map, filter, zip и другие. Понимание итераторов необходимо для работы с большими данными, так как они позволяют обрабатывать элементы по одному, не загружая всю последовательность в память. Также итераторы используются при создании пользовательских коллекций, которые должны поддерживать перебор.
Коротко
- Итератор — объект с методами
__next__и__iter__, возвращающий элементы по одному и выбрасывающийStopIterationв конце. - Любой итератор является итерируемым, но не наоборот.
- Итератор одноразовый: после исчерпания его нельзя переиспользовать.
- Итераторы позволяют эффективно работать с потоками данных, не загружая их целиком в память.
