Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
За что отвечает метод iter
Метод __iter__ — это магический метод в Python, который делает объект итерируемым. Он отвечает за инициализацию процесса перебора элементов объекта и должен возвращать итератор.
Основная концепция
Итерируемый объект (iterable) — это объект, по которому можно проводить перебор в цикле. Для этого Python вызывает __iter__(), который должен вернуть итератор.
# Базовая иерархия:
# Iterable (имеет __iter__) -> Iterator (имеет __iter__ и __next__)
my_list = [1, 2, 3]
# Когда вы пишете:
for element in my_list:
print(element)
# Python делает:
iterator = iter(my_list) # Вызывает my_list.__iter__()
while True:
try:
element = next(iterator) # Вызывает iterator.__next__()
print(element)
except StopIteration:
break
Разница между итерируемым и итератором
Итерируемый объект (Iterable):
- Имеет метод
__iter__() - Возвращает итератор
- Примеры: list, tuple, dict, set, string
Итератор (Iterator):
- Имеет методы
__iter__()и__next__() __iter__()возвращает себя (self)__next__()возвращает следующий элемент- Поднимает StopIteration когда элементы закончились
# Итерируемый объект НЕ итератор
my_list = [1, 2, 3]
print(hasattr(my_list, "__iter__")) # True
print(hasattr(my_list, "__next__")) # False
# Итератор - итерируемый объект
iterator = iter(my_list)
print(hasattr(iterator, "__iter__")) # True
print(hasattr(iterator, "__next__")) # True
Создание простого итерируемого класса
class Counter:
def __init__(self, max):
self.max = max
def __iter__(self):
# Возвращает итератор (может быть self или другой объект)
return CounterIterator(self.max)
class CounterIterator:
def __init__(self, max):
self.current = 0
self.max = max
def __iter__(self):
return self
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current
else:
raise StopIteration
# Использование
counter = Counter(3)
for num in counter:
print(num) # 1, 2, 3
Альтернатива: итератор и итерируемый в одном классе
class SimpleIterator:
def __init__(self, max):
self.max = max
self.current = 0
def __iter__(self):
return self # Возвращает саму себя
def __next__(self):
if self.current < self.max:
self.current += 1
return self.current
else:
raise StopIteration
# Использование
for num in SimpleIterator(3):
print(num) # 1, 2, 3
Практический пример: итерируемый класс для работы с файлом
class FileReader:
def __init__(self, filename):
self.filename = filename
def __iter__(self):
return FileIterator(self.filename)
class FileIterator:
def __init__(self, filename):
self.file = open(filename, "r")
def __iter__(self):
return self
def __next__(self):
line = self.file.readline()
if line:
return line.strip()
else:
self.file.close()
raise StopIteration
# Использование
for line in FileReader("data.txt"):
print(line) # Печатает строку за строкой
Встроенные типы с iter
# Список
my_list = [1, 2, 3]
iterator = iter(my_list) # Вызывает __iter__
print(next(iterator)) # 1
print(next(iterator)) # 2
print(next(iterator)) # 3
# next(iterator) # StopIteration
# Словарь (по ключам по умолчанию)
my_dict = {"a": 1, "b": 2, "c": 3}
for key in my_dict: # Использует __iter__
print(key) # a, b, c
# Строка
for char in "hello": # Использует __iter__
print(char) # h, e, l, l, o
Использование с встроенными функциями
class CustomRange:
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:
self.current += 1
return self.current - 1
else:
raise StopIteration
# Работает с встроенными функциями благодаря __iter__
custom = CustomRange(0, 5)
print(list(custom)) # [0, 1, 2, 3, 4]
print(max(CustomRange(10, 20))) # 19
print(sum(CustomRange(1, 5))) # 6
# Распаковка благодаря __iter__
a, b, c = CustomRange(0, 3) # a=0, b=1, c=2
Контекстный менеджер с итератором
class DataIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
def __len__(self):
return len(self.data)
data_iter = DataIterator([10, 20, 30, 40])
for value in data_iter:
print(value) # 10, 20, 30, 40
# Можно переитерировать, создав новый объект
for value in DataIterator([10, 20, 30, 40]):
print(value)
Генераторы используют iter автоматически
def my_generator(max):
current = 0
while current < max:
yield current
current += 1
# Генератор имеет __iter__ и __next__ по умолчанию
gen = my_generator(3)
print(hasattr(gen, "__iter__")) # True
print(hasattr(gen, "__next__")) # True
# Работает в цикле
for num in gen:
print(num) # 0, 1, 2
Важные замечания
- iter должен вернуть итератор — объект с методом
__next__ - Можно возвращать self — если класс одновременно является итератором
- Множественная итерация — список позволяет множественную итерацию, но некоторые итераторы нет
my_list = [1, 2, 3]
# Можно итерировать многократно
for x in my_list:
print(x)
for x in my_list: # Работает снова
print(x)
# Но с итератором файла это не сработает
reader = FileReader("data.txt")
for line in reader:
print(line)
for line in reader: # Ничего не напечатает - файл закрыт
print(line)
Резюме
Метод __iter__ критически важен для:
- Использования объекта в цикле
for - Распаковки значений
- Работы с встроенными функциями (list, sum, max, etc.)
- Создания пользовательских типов данных с поддержкой итерации
В заключение: __iter__ — это способ Python говорить объекту: "Дай мне итератор, я буду доставать из него элементы один за другим".