Вопрос проверяет понимание протокола итерации и того, какие методы делают объект итерируемым или последовательностью.
Итерируемый объект должен реализовывать метод __iter__, который возвращает итератор. Итератор, в свою очередь, должен реализовывать методы __iter__ и __next__. Последовательности часто дополнительно реализуют __len__ и __getitem__, что позволяет итерироваться по ним даже без явного __iter__. Python может использовать __getitem__, начиная с индекса 0, пока не получит исключение IndexError.
В Python существует так называемый протокол итерации. Объект считается итерируемым, если он реализует метод:
__iter__() — возвращает итератор
Итератор — это объект, который реализует:
__iter__() — возвращает сам себя
__next__() — возвращает следующий элемент или возбуждает StopIteration
Пример простого итератора:
class Counter:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
self.current += 1
return self.current
Последовательность может не реализовывать __iter__, но поддерживать:
__getitem__(index)
__len__()
В этом случае Python будет запрашивать элементы по индексам начиная с 0.
Пример:
class SimpleSeq:
def __getitem__(self, index):
if index >= 3:
raise IndexError
return index * 10
Чтобы объект был итерируемым, обычно достаточно реализовать __iter__. Для последовательностей также важно поддерживать доступ по индексу и длину. Это позволяет использовать объект в циклах for, генераторах и встроенных функциях.