Вопрос проверяет знание протокола итерации и того, как Python понимает, что элементы закончились.
StopIteration — это исключение, которое сообщает, что итератор больше не может вернуть элементов. Оно возникает, когда генератор завершает работу или итератор исчерпан. Цикл for и многие функции стандартной библиотеки автоматически перехватывают это исключение. Благодаря этому итерация завершается корректно.
Python использует единый протокол итерации для всех итерируемых объектов.
Определение: Итератор — объект, который реализует метод __next__() и возвращает следующий элемент или возбуждает StopIteration.
В генераторах
Когда выполнение функции доходит до конца:
def gen():
yield 1
g = gen()
print(next(g)) # 1
print(next(g)) # StopIteration
В пользовательских итераторах
Если реализуется __next__, нужно явно возбуждать исключение:
class Counter:
def __init__(self, limit):
self.i = 0
self.limit = limit
def __next__(self):
if self.i >= self.limit:
raise StopIteration
self.i += 1
return self.i
Внутри цикла for
Цикл делает примерно следующее:
# Упрощённая логика
it = iter(obj)
while True:
try:
item = next(it)
except StopIteration:
break
StopIteration — это стандартный механизм сигнализации об окончании данных. Благодаря ему любые итераторы, генераторы и контейнеры работают одинаково в for, list(), sum() и других функциях.
StopIteration — ключевая часть протокола итерации, позволяющая Python универсально определять, что последовательность закончилась.