J'ai écrit un objet conteneur personnalisé.
Selon cette page , je dois implémenter cette méthode sur mon objet:
__iter__(self)
Cependant, après avoir suivi le lien vers les types d'itérateur dans le manuel de référence Python, aucun exemple n'est donné sur la façon d'implémenter le vôtre.
Quelqu'un peut-il publier un extrait (ou un lien vers une ressource), qui montre comment faire cela?
Le conteneur que j'écris est une carte (c'est-à-dire stocke les valeurs par des clés uniques). les dicts peuvent être itérés comme ceci:
for k, v in mydict.items()
Dans ce cas, j'ai besoin de pouvoir renvoyer deux éléments (un tuple?) Dans l'itérateur. On ne sait toujours pas comment implémenter un tel itérateur (malgré les nombreuses réponses qui ont été aimablement fournies). Quelqu'un pourrait-il s'il vous plaît éclairer davantage sur la façon d'implémenter un itérateur pour un objet conteneur de type carte? (c'est-à-dire une classe personnalisée qui agit comme un dict)?
some_list
ont été générés.some_list
être épuisé.StopIteration
est automatiquement déclenché par Python lorsque la fonction génératrice revient, soit en appelant explicitement,return
soit en atteignant la fin de la fonction (qui, comme toutes les fonctions, a un implicitereturn None
à la fin). Le relèvement expliciteStopIteration
n'est pas nécessaire et à partir de Python 3.5 ne fonctionnera pas (voir PEP 479 ): tout comme les générateurs se transformentreturn
enStopIteration
, ils deviennent explicitesraise StopIteration
enRuntimeError
.Une autre option consiste à hériter de la classe de base abstraite appropriée du module `collections comme documenté ici .
Si le conteneur est son propre itérateur, vous pouvez hériter de
collections.Iterator
. Il vous suffit alors d'implémenter lanext
méthode.Un exemple est:
Pendant que vous regardez le
collections
module, envisagez d'hériter deSequence
,Mapping
ou d'une autre classe de base abstraite si cela est plus approprié. Voici un exemple deSequence
sous - classe:NB : Merci à Glenn Maynard d'avoir attiré mon attention sur la nécessité de clarifier la différence entre les itérateurs d'une part et les conteneurs itérables plutôt qu'itérateurs d'autre part.
la source
généralement,
__iter__()
retournez simplement self si vous avez déjà défini la méthode next () (objet générateur):voici un exemple factice de générateur:
mais
__iter__()
peut également être utilisé comme ceci: http://mail.python.org/pipermail/tutor/2006-January/044455.htmlla source
Si votre objet contient un ensemble de données auxquelles vous souhaitez lier l'itération de votre objet, vous pouvez tricher et faire ceci:
la source
hasattr
, utiliseztry/except AttributeError
L '"interface itérative" en python se compose de deux méthodes
__next__()
et__iter__()
. La__next__
fonction est la plus importante, car elle définit le comportement de l'itérateur - c'est-à-dire que la fonction détermine la valeur à renvoyer ensuite. La__iter__()
méthode est utilisée pour réinitialiser le point de départ de l'itération. Souvent, vous constaterez que cela__iter__()
peut simplement revenir à soi quand il__init__()
est utilisé pour définir le point de départ.Consultez le code suivant pour définir une classe inverse qui implémente l '"interface itérative" et définit un itérateur sur n'importe quelle instance de n'importe quelle classe de séquence. La
__next__()
méthode commence à la fin de la séquence et renvoie les valeurs dans l'ordre inverse de la séquence. Notez que les instances d'une classe implémentant "l'interface de séquence" doivent définir__len__()
une__getitem__()
méthode et une .la source
Pour répondre à la question sur les mappages : votre fourni
__iter__
doit itérer sur les clés du mappage. Ce qui suit est un exemple simple qui crée un mappagex -> x * x
et fonctionne sur Python3 en étendant le mappage ABC.la source
Au cas où vous ne voudriez pas hériter
dict
comme d'autres l'ont suggéré, voici la réponse directe à la question sur la façon de mettre en œuvre__iter__
pour un exemple brut d'un dict personnalisé:Cela utilise un générateur, qui est bien décrit ici .
Puisque nous héritons de
Mapping
, vous devez également implémenter__getitem__
et__len__
:la source
Une option qui pourrait fonctionner dans certains cas consiste à faire hériter de votre classe personnalisée
dict
. Cela semble être un choix logique s'il agit comme un dict; peut-être que ça devrait être un dict. De cette façon, vous obtenez une itération de type dict gratuitement.Production:
la source
exemple pour hériter de dict, modifier sa
iter
clé, par exemple, skip2
lors de la boucle forla source