Что это такое
Паттерн Итератор (Iterator) обходит коллекцию, не раскрывая, как она хранится. Вызывающий код спрашивает «есть ли ещё?» и «дай следующий элемент» — а где живут данные, в списке, дереве или базе данных, остаётся скрытым.
Для обычных списков и словарей цикл for в Python уже и есть ваш итератор. Паттерн важен, когда хранилище скрыто или обход сложен, — и ответ Python здесь __iter__: реализуйте его, часто в виде генератора, и любой объект будет работать с for ... in.
Пример: обход плейлиста
Плейлист держит свои песни в секрете. Он реализует __iter__ как генератор, который выдаёт по одной песне за раз, — хранилище за ним можно полностью заменить, и ни один вызывающий код не сломается.
Обход выполняет генератор
Цикл никогда не обращается к списку внутри плейлиста. Замените список на связный список или ленивую загрузку — и тот же цикл for по-прежнему работает без изменений.
Вывод: полная программа на Python
from typing import Iterator
class Playlist:
def __init__(self, songs: list[str]) -> None:
self._songs = songs
# Итератор обходит коллекцию, не раскрывая список.
def __iter__(self) -> Iterator[str]:
for song in self._songs:
yield song
playlist = Playlist(["intro", "verse", "chorus"])
for song in playlist:
print("играет:", song)
Когда использовать
Используйте его, когда внутреннее устройство коллекции должно оставаться скрытым, когда обход нетривиален (деревья, страницы из API) или когда нужно несколько независимых обходов одновременно.
Не используйте его для списков и словарей в собственном коде — прямой цикл по ним короче, быстрее и понятен любому читателю.
Плюсы и минусы
Плюсы: хранилище остаётся скрытым и его можно менять; несколько обходов могут идти независимо — каждый цикл for получает новый генератор; сложный обход пишется один раз.
Минусы: больше кода, чем при прямом цикле; активный итератор по изменяющейся коллекции — классический источник трудноуловимых ошибок.