Каким образом следует реализовать методы внутри собственного класса для обеспечения его возможности итерирования?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Чтобы объект собственного класса можно было использовать в for, он должен реализовывать итераторный протокол: возвращать итератор через __iter__() и выдавать элементы через __next__(). Если нужен только сам объект-коллекция, достаточно, чтобы __iter__() возвращал итератор по внутренним данным. Для простых случаев часто проще делегировать итерирование встроенному контейнеру, например списку.
Определение:
Итерируемым считается объект, по которому можно пройтись циклом for. В Python это обычно достигается двумя способами: либо класс сам является итератором и реализует __iter__() и __next__(), либо __iter__() возвращает отдельный итератор, например iter(self.items).
__iter__() должен вернуть объект, который умеет выдавать элементы по одному. __next__() должен возвращать следующий элемент и выбрасывать StopIteration, когда элементы закончились.
Пример использования:
class Numbers:
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
self.current = self.start
return self
def __next__(self):
if self.current > self.end:
raise StopIteration
value = self.current
self.current += 1
return value
nums = Numbers(1, 3)
for n in nums:
print(n)
Пояснение кода:
- В
__iter__()объект подготавливается к обходу: счётчикcurrentустанавливается в начало диапазона. __iter__()возвращаетself, значит сам объект выступает итератором.- Каждый вызов
__next__()возвращает текущее значение и сдвигает счётчик дальше. - Когда значения заканчиваются,
__next__()выбрасываетStopIteration, и циклforзавершается.
Если нужно, чтобы класс был просто итерируемым, но не итератором, можно сделать так:
class Numbers:
def __init__(self, values):
self.values = values
def __iter__(self):
return iter(self.values)
Здесь код не нужно писать вручную для __next__(), потому что итерирование делегируется списку values.
Ключевые моменты:
- Для поддержки
forнужен итераторный протокол:__iter__()и обычно__next__(). __next__()обязан завершать обход черезStopIteration.- Если объект одноразовый как итератор,
__iter__()часто возвращаетself. - Если объект — контейнер, лучше
__iter__()возвращать отдельный итератор по внутренней структуре. - Для простых коллекций безопаснее и проще делегировать
iter(...)встроенным типам.