Может ли кто-нибудь сказать мне, почему существует итерация созданного мной объекта? - PullRequest
0 голосов
/ 27 мая 2020

Я новичок в Python, и сейчас я склоняюсь к итераторам и итераторам. Может ли кто-нибудь сказать мне, почему, когда я запускаю этот код, программа печатает числа до бесконечности? Мой главный вопрос: почему объект, который я создал, выполняет итерацию для l oop? который является «элементом» в obj1, который выполняет итерацию? когда я говорю для элемента в [1,2,3], я знаю, что каждый раз на каждой итерации элементом является номер списка но здесь? Большое спасибо за вашу помощь, потому что я очень смущен ..

class Inter:
  def __init__(self,value):
    self.value = value

  def __iter__(self):
    return self

  def __next__(self):
    count = self.value
    self.value +=1
    return count


obj1 = Inter(1)
for item in obj1:
   print(item)

1 Ответ

2 голосов
/ 27 мая 2020

for l oop всегда вызывает iter, чтобы получить итератор для obj1. Грубо говоря, l oop это то же самое, что

obj_iter = iter(obj1)  # obj_iter = obj1.__iter__()
while True:
    try:
        item = next(obj_iter)  # item = obj_iter.__next__()
    except StopIteration:
        break
    print(item)

obj_iter - это возвращаемое значение obj1.__iter__ (так что obj1 сам).

next(obj_iter) - это возвращаемое значение obj_iter.__next__(). Ваш метод __next__ никогда не поднимает StopIteration; it всегда возвращает какое-то новое значение.

Чтобы продемонстрировать использование StopIteration, рассмотрим небольшую модификацию, которая создает только конечный поток значений меньше 10:

  def __next__(self):
    count = self.value
    <b>if count >= 10:
        raise StopIteration</b>
    self.value +=1
    return count

Несколько примечаний:

  1. Экземпляр Inter повторяется, потому что __iter__ определено. Итератор - это то, что знает, как создать или получить итератор.
  2. Экземпляр Inter является итератором, потому что определено __next__. Итератор - это то, что знает, как создать следующее значение из итерируемого.
  3. Все типы итераторов можно (и по соглашению) сделать итеративными, определив __iter__ = lambda self: self: итератор сам является повторяемым
  4. Однако не все повторяющиеся типы являются итераторами. list.__iter__ не возвращает список; он возвращает экземпляр list_iterator. Этот экземпляр сохраняет ссылку на исходный список и поддерживает свое собственное состояние для определения list_iterator.__next__, которое будет использоваться.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...