Подтвердить что ты не робот

Как работает __iter__?

Несмотря на то, что я читал об этом, я до сих пор не понимаю, как работает __iter__. Что было бы простым объяснением?

Я видел def__iter__(self): return self. Я не вижу, как это работает, или о том, как это работает.

4b9b3361

Ответ 1

Итератору необходимо определить два метода: __iter__() и __next__() (next() в python2). Обычно сам объект определяет метод __next__() или next(), поэтому он просто возвращает себя как итератор. Это создает итерабельность, которая сама по себе является итератором. Эти методы используются операторами for и in.

Python 3 docs: docs.python.org/3/library/stdtypes.html#iterator-types

Python 2 docs: docs.python.org/2/library/stdtypes.html#iterator-types

Ответ 2

Как я могу сказать:

__iter__ определяет метод класса, который возвращает итератор (объект, который последовательно дает следующий элемент, содержащийся в вашем объекте).

Объект итератора, возвращаемый __iter__(), может быть почти любым объектом, если он определяет метод next().

Метод next вызывается операторами типа for ... in ..., чтобы получить следующий элемент, а next() должен поднимать исключение StopIteration, когда больше нет элементов.

Что бы это ни значило, это позволяет определить, как выполняется повторение вашего объекта, а __iter__ предоставляет общий интерфейс, с которым любая другая функция python знает, как работать.

Ответ 3

Спецификацией для def __iter__(self): являются: он возвращает итератор. Итак, если self - итератор, то return self явно уместен.

"Являясь итератором" означает "имеющий метод __next__(self)" (в Python 3, в Python 2, имя рассматриваемого метода, к сожалению, просто next, очевидно, что сбой дизайна имени для специального метода).

В Python 2.6 и выше лучшим способом реализации итератора обычно является использование соответствующего абстрактного базового класса из стандартной библиотеки collections module - в Python 2.6, код может быть (не забудьте вызвать метод __next__ вместо этого в Python 3):

import collections

class infinite23s(collections.Iterator):
  def next(self): return 23

экземпляр этого класса будет возвращать бесконечно много копий 23 при повторении (например, itertools.repeat(23)), поэтому цикл должен быть завершен иначе. Дело в том, что подклассификация collections.Iterator добавляет правильный метод __iter__ от вашего имени - здесь не большая вещь, но хороший общий принцип (избегайте повторяющихся, стандартных шаблонов, таких как стандартные однострочные итераторы __iter__ - в повторение, нет добавленной стоимости и большого количества вычитаемого значения! -).

Ответ 4

Класс, поддерживающий метод __iter__, вернет экземпляр объекта итератора: объект, поддерживающий метод next(). Этот объект будет использоваться в заявлениях "за" и "в".

Ответ 5

В Python итератором является любой объект, поддерживающий протокол итератора. Часть этого протокола заключается в том, что объект должен иметь метод __iter__(), который возвращает объект итератора. Я полагаю, это дает вам некоторую гибкость, так что объект может передать обязанности итератора внутреннему классу или создать какой-то специальный объект. В любом случае метод __iter__() обычно имеет только одну строку, и эта строка часто просто return self

Другая часть протокола - это метод next(), и именно здесь выполняется настоящая работа. Этот метод должен выяснить или создать или получить следующее, и вернуть его. Возможно, потребуется отслеживать, где он находится, чтобы в следующий раз, когда он был вызван, он действительно возвращает следующую вещь.

Когда у вас есть объект, который возвращает следующую вещь в последовательности, вы можете свернуть цикл for, который выглядит следующим образом:

myname = "Fredericus"
x = []
for i in [1,2,3,4,5,6,7,8,9,10]:
   x.append(myname[i-1])
   i = i + 1 # get the next i
print x

в это:

myname = "Fredericus"
x = [myname[i] for i in range(10)]
print x

Обратите внимание, что где-то там, где у нас есть код, который получает следующее значение i, потому что диапазон (10) является объектом, который ПОСЛЕДУЕТ в протокол итератора, а понимание списка - это конструкция, которая ИСПОЛЬЗУЕТ протокол итератора.

Вы также можете напрямую использовать протокол итератора. Например, при написании скриптов для обработки CSV файлов я часто пишу это:

mydata = csv.reader(open('stuff.csv')
mydata.next()
for row in mydata:
    # do something with the row.

Я использую итератор напрямую, вызывая next(), чтобы пропустить строку заголовка, а затем косвенно использовать его с помощью встроенного оператора in в инструкции for.