Вопрос

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

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

Это было полезно?

Решение

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

Другие советы

Насколько я могу выразиться:

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

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

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

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

Спецификации для def __iter __ (self): : он возвращает итератор. Итак, если self является итератором, return self явно подходит.

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

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

import collections

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

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

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

В 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, потому что range (10) - это объект, следующий за протоколом итератора, а понимание списка - это конструкция, которая использует протокол итератора.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top