2009-10-22 3 views
16

Obwohl ich es gelesen habe, verstehe ich immer noch nicht, wie __iter__ funktioniert. Was wäre eine einfache Erklärung?Wie funktioniert __iter__?

Ich habe def__iter__(self): return self gesehen. Ich verstehe nicht, wie das funktioniert oder wie es funktioniert.

+3

Welche Kapitel des Buchs? Das wird uns helfen, die Quelle Ihrer Verwirrung einzugrenzen. –

+0

Lernen Python Kapitel 24 Seite 493 - 495 – sss

+0

Wenn Sie in der Standardbibliothek Dokumentation itertools Modul suchen, werden Sie eine Reihe von Funktionen finden, die die __iter __() -Methode benötigen. –

Antwort

6

Ein Iterator muss zwei Methoden definieren: __iter__() und __next__() (next() in Python2). Normalerweise definiert das Objekt selbst die __next__() oder next() Methode, so dass es sich selbst als Iterator zurückgibt. Dies erzeugt einen iterierbaren, der auch selbst ein Iterator ist. Diese Methoden werden von for und in Anweisungen verwendet.

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

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

+4

In Python 3 wurde '__next __()' anstelle von 'next()' erstellt. – JeromeJ

+3

Das ist verwirrend. Vor allem, weil Sie etwas sagen, dann sagen Sie sofort, es ist eine Lüge. Lol, aktualisieren Sie es einfach, um korrekt zu sein –

2

Eine Klasse, die die Methode __iter__ unterstützt, gibt eine Iterator-Objektinstanz zurück: ein Objekt, das die Methode next() unterstützt. Dieses Objekt wird in den Aussagen "für" und "in" nützlich sein.

21

So einfach wie ich kann es ausdrückte:

__iter__ definiert eine Methode für eine Klasse, die einen Iterator zurück (ein Objekt, das von Ihrem Objekt enthält das nächste Element nacheinander ergibt).

Das Iterator-Objekt, das __iter__() zurückgibt, kann so ziemlich jedes Objekt sein, solange es eine next() Methode definiert.

Die next Methode wird durch Aussagen wie for ... in ... genannt werden, um den nächsten Punkt zu erhalten, und next() sollte die StopIteration Ausnahme auslösen, wenn es keine weiteren Elemente sind.

Was ist toll daran ist, es lässt Sie definieren, wie das Objekt iteriert und __iter__ bietet eine gemeinsame Schnittstelle, die jede andere Python-Funktion weiß, wie man mit arbeiten.

2

In Python ist ein Iterator jedes Objekt, das das Iteratorprotokoll unterstützt. Teil dieses Protokolls ist, dass das Objekt eine __iter__()-Methode haben muss, die das Iterator-Objekt zurückgibt. Ich nehme an, dies gibt Ihnen eine gewisse Flexibilität, so dass ein Objekt die Iterator-Verantwortlichkeiten an eine interne Klasse weitergeben oder ein spezielles Objekt erstellen kann. Auf jeden Fall hat die __iter__() Verfahren in der Regel nur eine Zeile und diese Linie ist oft einfach return self

Der andere Teil des Protokolls ist die next() Methode, und das ist, wo die eigentliche Arbeit erledigt ist. Diese Methode muss herausfinden oder erstellen oder die nächste Sache bekommen und es zurückgeben. Es muss möglicherweise nachverfolgen, wo es ist, damit es beim nächsten Aufruf das nächste Ding zurückgibt.

Wenn Sie ein Objekt haben, das nächste, was in einer Sequenz zurückgibt, können Sie eine for-Schleife kollabieren, die wie folgt aussieht:

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 

in diese:

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

Hinweis, dass es Nirgendwo, wo wir Code haben, der den nächsten Wert von i erhält, weil Bereich (10) ein Objekt ist, das das Iteratorprotokoll FOLGT, und das Listenverständnis ist ein Konstrukt, das das Iteratorprotokoll VERWENDET.

Sie können das Iteratorprotokoll auch direkt verwenden. Zum Beispiel, wenn das Schreiben von Skripts CSV-Dateien zu verarbeiten, schreibe ich oft diese:

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

Ich bin mit dem Iterator direkt von next() Aufruf der Kopfzeile überspringen, dann indirekt über den eingebauten in Operator in den for mit Erklärung.

5

Die Spezifikationen für def __iter__(self): sind: Es gibt einen Iterator zurück. Also, wenn self ein Iterator ist, ist return self eindeutig angemessen.

"Als ein Iterator" bedeutet "ein Verfahren mit __next__(self)" (in Python 3; Python in 2, ist der Name des Verfahrens in Frage leider Klar next stattdessen eindeutig ein Name Entwurf Glitch für eine spezielle Methode).

In Python 2.6 und höher, der beste Weg, einen Iterator zu implementieren, ist im Allgemeinen die entsprechende abstrakte Basisklasse aus der collections Standardbibliothek module zu verwenden - in Python 2.6, könnte der Code sein (denken Sie daran __next__ die Methode aufzurufen, statt in Python 3):

import collections 

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

eine Instanz dieser Klasse wird unendlich viele Kopien von 23 zurück, wenn auf (wie itertools.repeat(23) iteriert), so muss die Schleife auf andere Weise beendet werden. Der Punkt ist, dass Unterklasse collections.Iterator die richtige __iter__ Methode in Ihrem Namen hinzufügt - keine große Sache hier, aber ein gutes allgemeines Prinzip (repetitive, Boilerplate-Code wie Iteratoren Standard-One-Line __iter__ vermeiden - in der Wiederholung gibt es keinen Mehrwert und viel subtrahierter Wert! -).

+0

Im zweiten Absatz hat die SO-Formatierung "__next__" in Fettdruck "next" geändert. Es lohnt sich, für Klarheit zu sorgen. –

+0

@Craig, aber es soll 'next' nicht' __next__' sein –

+0

In Python 2 ist es 'next', aber in Python 3 wurde es in' __next__' umbenannt, wie Alex sagen will. –