Wörterbücher sind kein Selbst Iterator (die sich nur über einmal laufen werden können). Sie machen sie normalerweise iterable, ein Objekt, für das Sie mehrere Iteratoren stattdessen produzieren können.
Lassen Sie die Methode next
insgesamt fallen, und geben Sie bei jedem Aufruf ein iterbares Objekt mit __iter__
zurück. Das kann so einfach sein wie nur einen Iterator für self.container
Rückkehr:
def __iter__(self):
return iter(self.container)
Wenn Sie müssen Ihre Klasse machen ein Iterator, musst du irgendwie eine aktuelle Iteration Position verfolgen und erhöhen StopIteration
, sobald Sie erreichen die ' Ende'. Eine naive Implementierung könnte das iter(self.container)
Objekt auf self
das erste Mal __iter__
genannt wird gespeichert sein:
def __iter__(self):
return self
def next(self):
if not hasattr(self, '_iter'):
self._iter = iter(self.container)
return next(self._iter)
an welchem Punkt des iter(self.container)
Objekt übernimmt Iteration Position für Sie von Tracking und wird StopIteration
erhöhen, wenn das Ende erreicht ist . Es wird auch eine Ausnahme ausgelöst, wenn das zugrundeliegende Wörterbuch geändert wurde (wenn Schlüssel hinzugefügt oder gelöscht wurden) und die Iterationsreihenfolge unterbrochen wurde.
Ein anderer Weg, dies zu tun wäre, zu speichern, nur in ganzzahligen Position und Index in list(self.container)
jedes Mal, und einfach die Tatsache ignorieren, dass Einfügen oder Löschen die Iterationsreihenfolge eines Wörterbuchs ändern kann:
_iter_index = 0
def __iter__(self):
return self
def next(self):
idx = self._iter_index
if idx is None or idx >= len(self.container):
# once we reach the end, all iteration is done, end of.
self._iter_index = None
raise StopIteration()
value = list(self.container)[idx]
self._iter_index = idx + 1
return value
In In beiden Fällen ist Ihr Objekt dann ein Iterator, der nur über einmal iteriert werden kann. Wenn Sie das Ende erreicht haben, können Sie es nicht erneut starten.