Я написал собственный объект-контейнер.
Согласно этой странице , мне нужно реализовать этот метод на моем объекте:
__iter__(self)
Однако, после перехода по ссылке на Типы итераторов в справочном руководстве Python, нет примеров того, как реализовать свои собственные.
Может ли кто-нибудь опубликовать фрагмент (или ссылку на ресурс), в котором показано, как это сделать?
Контейнер, который я пишу, представляет собой карту (т.е. хранит значения по уникальным ключам). dicts можно повторять так:
for k, v in mydict.items()
В этом случае мне нужно иметь возможность вернуть два элемента (кортеж?) В итераторе. По-прежнему не ясно, как реализовать такой итератор (несмотря на несколько любезно предоставленных ответов). Может ли кто-нибудь пролить свет на то, как реализовать итератор для объекта контейнера, подобного карте? (т.е. настраиваемый класс, который действует как диктатор)?
some_list
переданы.some_list
будет исчерпано.StopIteration
автоматически вызывается Python при возврате функции генератора, либо при явном вызове,return
либо при достижении конца функции (которая, как и все функции, имеет неявное значениеreturn None
в конце). Явное повышениеStopIteration
не требуется, и в Python 3.5 фактически не будет работать (см. PEP 479 ): так же, как генераторы превращаютсяreturn
вStopIteration
, они превращаются в явныйraise StopIteration
вRuntimeError
.Другой вариант - унаследовать соответствующий абстрактный базовый класс от модуля collections, как описано здесь .
Если контейнер является собственным итератором, вы можете наследовать от
collections.Iterator
.next
Тогда вам нужно только реализовать метод.Пример:
В то время как вы смотрите на
collections
модуле, рассмотреть вопрос о наследовании отSequence
,Mapping
или другого абстрактного базового класса , если это более уместно. Вот примерSequence
подкласса:NB : Спасибо Гленну Мейнарду за то, что обратил мое внимание на необходимость прояснить разницу между итераторами, с одной стороны, и контейнерами, которые являются итераторами, а не итераторами, с другой.
источник
обычно
__iter__()
просто возвращайте self, если вы уже определили метод next () (объект-генератор):вот фиктивный пример генератора:
но
__iter__()
также можно использовать так: http://mail.python.org/pipermail/tutor/2006-January/044455.htmlисточник
Если ваш объект содержит набор данных, к которым вы хотите привязать его объект, вы можете обмануть и сделать следующее:
источник
hasattr
используйтеtry/except AttributeError
«Итерируемый интерфейс» в Python состоит из двух методов
__next__()
и__iter__()
.__next__
Функция является наиболее важной, так как она определяет поведение итератора - то есть, функция определяет , какое значение должно быть возвращено в следующем.__iter__()
Метод используется для сброса начальной точки итерации. Часто вы обнаружите, что__iter__()
может просто возвращать self, когда__init__()
используется для установки начальной точки.См. Следующий код для определения обратного класса, который реализует «итеративный интерфейс» и определяет итератор для любого экземпляра из любого класса последовательности.
__next__()
Способ начинается в конце значений последовательности и возвращает в обратном порядке последовательности. Обратите внимание, что экземпляры из класса, реализующего «интерфейс последовательности», должны определять__len__()
и__getitem__()
метод.источник
Чтобы ответить на вопрос о сопоставлениях : предоставленный вами
__iter__
должен перебирать ключи сопоставления. Ниже приведен простой пример, который создает отображениеx -> x * x
и работает на Python3, расширяя отображение ABC.источник
Если вы не хотите наследовать,
dict
как предлагали другие, вот прямой ответ на вопрос о том, как реализовать__iter__
грубый пример настраиваемого dict:Здесь используется генератор, который хорошо описан здесь .
Поскольку мы наследуем от
Mapping
, вам также необходимо реализовать__getitem__
и__len__
:источник
Один из вариантов, который может работать в некоторых случаях, - это сделать ваш собственный класс наследованием от
dict
. Это кажется логичным выбором, если действует как диктат; может быть, это должен быть диктат. Таким образом, вы получаете бесплатную итерацию в стиле dict.Вывод:
источник
например, для унаследованного от dict, измените его
iter
, например, клавишу пропуска2
в цикле forисточник