Ist ein Iterator auch ein iterabler?

9

Ich habe das gefunden:

%Vor%

Hat ein Iterator immer die Methode __iter__ ?

Nach Ссылка ist ein Iterator auch ein iterabler. Wenn es wahr ist, dass ein Iterator immer __iter__ Methode hat?

    
Ben 07.09.2017, 22:43
quelle

4 Antworten

8

Ein iterabler Prozess muss eine __iter__ -Methode oder eine __getitem__ -Methode implementieren :

  

Ein Objekt kann mit for iteriert werden, wenn es __iter__() oder __getitem__() implementiert.

Ein Iterator benötigt eine __iter__ -Methode (die self zurückgibt) und eine __next__ -Methode (ich bin nicht 100% ig sicher über __next__ ).

es stimmt, dass ein Iterator immer __iter__ Methode?

hat

Ja!

Dies ist auch im Datenmodell dokumentiert:

  

object.__iter__(self)

     

Diese Methode wird aufgerufen, wenn ein Iterator für einen Container erforderlich ist. Diese Methode sollte ein neues Iteratorobjekt zurückgeben, das über alle Objekte im Container iterieren kann. Für Zuordnungen sollte es über die Schlüssel des Containers iterieren.

     

Iterator-Objekte müssen diese Methode ebenfalls implementieren. Sie müssen sich selbst zurückgeben . Weitere Informationen zu Iterator-Objekten finden Sie unter Iterator-Typen.

(Betonung meiner)

Was Ihre zweite Frage betrifft:

Ist ein Iterator auch ein iterabler?

Ja, weil es eine Methode __iter__ hat.

Zusätzliche Hinweise

Neben der formalen Implementierung ist es einfach zu überprüfen, ob etwas iterierbar ist, indem einfach überprüft wird, ob iter() darauf aufgerufen werden kann:

%Vor%

Ebenso ist es möglich, zu überprüfen, ob etwas ein Iterator ist, indem überprüft wird, ob iter() aufgerufen hat, was sich selbst zurückgibt:

%Vor%

Aber benutze sie nicht im Entwicklungscode, diese sind nur für "Visualisierung". Meistens iterieren Sie einfach über etwas mit for ... in ... oder wenn Sie einen Iterator benötigen, verwenden Sie iterator = iter(...) und bearbeiten dann den Iterator, indem Sie next(iterator) aufrufen, bis ein StopIteration ausgegeben wird.

    
MSeifert 07.09.2017, 22:49
quelle
7

Ein Iterator ist iterierbar . Und ja, ein Iterator hat immer eine __iter__ -Methode.

Aufruf von iter für einen Iterator, der den __iter__ Hook aufruft, wird zurückgegeben derselbe Iterator:

%Vor%

Ein klassisches Beispiel für Methodenverkettung .

Wie Sie sicherlich bemerkt haben, folgen die meisten Implementierungen des Iterator-Protokolls für benutzerdefinierte Klassen immer:

%Vor%

Dies ist der Fall, wenn die Iteration nicht an einen anderen Iterator delegiert wird, zB über return iter(...) .

Es wäre ziemlich kontraintuitiv für einen Iterator , das Iterator-Protokoll denkst du nicht? Die __iter__ Implementierung des Protokolls wird im Folgenden beschrieben:

%Vor%      

Geben Sie das Iteratorobjekt selbst zurück. Dies ist erforderlich, um beides zu ermöglichen   Container und Iteratoren, die mit den Anweisungen for und in verwendet werden.

[ Hervorhebung von mir ]

Dieses Verhalten ist erwartungsgemäß konsistent mit Iterator-Objekten, die von Builtins zurückgegeben werden:

%Vor%

P.S .: Ich entschuldige mich dafür, dass ich wiederholt donnert habe; es sieht so aus, als ob es das Richtige ist. Aber es ist nicht !

    
Moses Koledoye 07.09.2017 22:48
quelle
1

Ein Iterator ist iterierbar.

Das ist dokumentiert und erklärt hier :

  

Iteratoren müssen eine __iter__() -Methode haben, die das Iterator-Objekt selbst zurückgibt, so dass jeder Iterator auch iterierbar ist

Ein iterables ist nicht notwendigerweise ein Iterator

Iteratoren müssen per Definition eine __next__ -Methode haben. Um ein einfaches Gegenbeispiel zu geben:

%Vor%

Ein String-Objekt ist ein iterabler, aber kein Iterator.

    
wim 07.09.2017 22:55
quelle
1

AKTUALISIERT:

Ich stehe korrigiert.

Alle Iteratoren haben __iter__ . Aber nicht alle Iterables sind Iteratoren.

Bei iterable hat entweder __iter__ oder __getitem__ .

Zum Beispiel ist das Folgende ein Iterable, das kein Iterator ist. Ich kann klar über "c" iterieren, aber es hat keine Methode __iter__ :

%Vor%

UPDATE 2:

Nur weil ein Objekt __iter__ hat, bedeutet das nicht, dass ein __next__ iterierbar ist. Im Falle von Generator-Iteratoren reicht __iter__ aus, um iterierbar zu sein. Zum Beispiel:

%Vor%     
RobertB 07.09.2017 22:53
quelle