Python Iterator Pattern einfach erklärt: So implementierst du es
Mit __iter__ und __next__ implementierst du das Iterator Pattern in Python – für sequenziellen Zugriff ohne interne Struktur offenzulegen.
By Marcel Schmidtpeter 26 Sept 2026
Stell dir vor, du programmierst in deiner Ausbildung eine Playlist-Verwaltung. Die Songs liegen in einer Liste - kein Problem. Aber was, wenn die Daten plötzlich aus einer Datenbank kommen, aus einer Datei oder sogar live von einer API? Genau hier rettet dich das Iterator Pattern in Python: Dein Code bleibt identisch, egal woher die Daten stammen. Die `for`-Schleife funktioniert einfach weiter.
Das Iterator Pattern ist eines der ältesten und praktischsten Entwurfsmuster (Design Patterns) überhaupt. In Python ist es so tief in die Sprache eingebaut, dass du es täglich nutzt - oft ohne es zu wissen. Ob du Azubi, Student oder Berufseinsteiger bist: Wenn du verstehst, wie Iteratoren funktionieren, verstehst du, wie Python unter der Haube tickt.
Was ist das Iterator Pattern in Python?
Das Iterator Pattern ist ein Entwurfsmuster, das dir einen einheitlichen Weg bietet, nacheinander auf Elemente einer Sammlung zuzugreifen - ohne die innere Struktur der Sammlung offenzulegen. Statt zu wissen, *wie* die Daten gespeichert sind, fragst du nur: "Gibt es noch ein nächstes Element?"
Stell dir einen Kellner in einem Restaurant vor. Er bringt dir Gericht für Gericht aus der Küche. Du musst nicht wissen, ob die Küche 3 Töpfe oder 30 hat oder wie die Bestellungen verwaltet werden. Du bekommst einfach das nächste Gericht, bis nichts mehr kommt.
In Python stecken dahinter zwei dunder-Methoden (das sind Methoden mit doppelten Unterstrichen wie `__iter__`):
`__iter__()` macht ein Objekt zu einem Iterable - also etwas, über das du iterieren *kannst*
`__next__()` liefert das nächste Element und wirft eine `StopIteration`, wenn nichts mehr kommt
Merke: Das Iterator Pattern trennt die Frage "Wie durchlaufe ich Daten?" von der Frage "Wie sind die Daten gespeichert?"
Was ist der Unterschied zwischen Iterable und Iterator?
Ein Iterable ist ein Objekt, das `__iter__()` implementiert und dir einen Iterator zurückgibt. Der Iterator selbst ist das Objekt, das sich den aktuellen Zustand merkt und über `__next__()` Elemente liefert. Die offizielle Python-Dokumentation zum Iterator-Protokoll beschreibt genau dieses Zusammenspiel.
Aspekt | Iterable | Iterator |
Methode | `__iter__()` | `__iter__()` + `__next__()` |
Aufgabe | Kann durchlaufen werden | Liefert Elemente nacheinander |
Zustand | Merkt sich nichts | Merkt sich die aktuelle Position |
Mehrfach durchlaufen? | Ja, liefert neuen Iterator | Nein, nach `StopIteration` erschöpft |
Die Analogie: Ein Buch (Iterable) kannst du mehrfach lesen. Ein Lesezeichen (Iterator) zeigt genau eine Position - ist das Buch zu Ende, hilft weiteres Umblättern nichts mehr.
Wenn du die Grundlagen zu `__iter__` und `__next__` vertiefen willst, lies dir auch unseren Beitrag Iterable und Iterator in Python durch.
Was macht die for-Schleife wirklich?
Die `for`-Schleife in Python ist eigentlich verkleideter Iteratoren-Code. Sie ruft im Hintergrund `iter()` und `next()` für dich auf. Diese beiden Schreibweisen sind identisch:
zahlen = [10, 20, 30]
# Variante 1: die normale for-Schleife
for zahl in zahlen:
print(zahl)
# Variante 2: das, was Python intern macht
iterator = iter(zahlen)
while True:
try:
zahl = next(iterator)
print(zahl)
except StopIteration:
breakBeide Varianten geben `10`, `20` und `30` aus. Warum ist das wichtig zu wissen? Weil jede Klasse, die das Iterator-Protokoll implementiert, automatisch mit `for`, List Comprehensions oder `sum()` funktioniert - ohne dass du eine Zeile extra schreiben musst.
Merke: Wer `__iter__()` und `__next__()` implementiert, bekommt `for`, List Comprehensions und `sum()` geschenkt - ganz ohne Extra-Code.
So implementierst du das Iterator Pattern selbst
Du implementierst das Pattern, indem du zwei Rollen sauber trennst: Das Iterable implementiert `__iter__()` und gibt einen frischen Iterator zurück. Der Iterator implementiert `__next__()` und liefert Elemente, bis eine `StopIteration`-Exception geworfen wird.
Hier ein vollständiges Beispiel - eine Aufgabenliste, die nur unerledigte Aufgaben nach und nach ausgibt:
class AufgabenListe:
def __init__(self, aufgaben):
self.aufgaben = aufgaben
def __iter__(self):
# Frischen Iterator mit eigenem Zustand zurueckgeben
return AufgabenListeIterator(self.aufgaben)
class AufgabenListeIterator:
def __init__(self, aufgaben):
self.aufgaben = aufgaben
self.index = 0
def __iter__(self):
return self
def __next__(self):
# Unerledigte Aufgaben weitersuchen
while self.index < len(self.aufgaben):
aufgabe = self.aufgaben[self.index]
self.index += 1
if not aufgabe["erledigt"]:
return aufgabe["titel"]
raise StopIteration
# Anwendung
aufgaben = [
{"titel": "Doku lesen", "erledigt": False},
{"titel": "Mail beantworten", "erledigt": True},
{"titel": "Refactoring", "erledigt": False},
]
liste = AufgabenListe(aufgaben)
for titel in liste:
print("Offen:", titel)
# Ausgabe: Offen: Doku lesen
# Offen: Refactoring
# Geht auch ein zweites Mal, weil __iter__ einen frischen Iterator liefert
for titel in liste:
print("Nochmal:", titel)Die Trennung in zwei Klassen ist die saubere Variante nach dem klassischen Pattern: `AufgabenListe` ist das Iterable und weiß nur, wie man einen Iterator baut. `AufgabenListeIterator` hält den Zustand des Durchlaufs. Genau deshalb kannst du dieselbe Liste mehrfach durchlaufen.
Wann brauchst du eigene Iteratoren wirklich?
In der Praxis brauchst du eigene Iteratoren immer dann, wenn du Daten nicht komplett im Speicher haben willst oder einen speziellen Durchlauf-Algorithmus hast. Klassische Fälle aus dem Arbeitsalltag:
Große Dateien Zeile für Zeile lesen - Dateiobjekte in Python sind selbst Iteratoren (mehr dazu in Python Datei lesen schreiben)
Unendliche Folgen - etwa eine Sequenz von IDs, die erst bei Bedarf erzeugt werden
Eigene Datenstrukturen - ein Binärbaum, der bei `for` eine Inorder-Traversierung liefert
Ein kurzes Beispiel für eine unendliche Folge:
class QuadratZahlen:
def __init__(self):
self.n = 0
def __iter__(self):
return self
def __next__(self):
self.n += 1
return self.n * self.n
quadrate = QuadratZahlen()
for q in quadrate:
print(q)
if q > 100:
break
# Ausgabe: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121Ohne `break` läuft diese Schleife endlos - die Folge ist ja unendlich. Genau das ist die Stärke: Elemente entstehen erst, wenn sie angefragt werden.
Kleiner Tipp: Für viele Fälle sind Generatoren (Funktionen mit `yield`) die kürzere Alternative zu eigenen Iterator-Klassen. Die Logik dahinter ist identisch - auch ein Generator implementiert `__iter__` und `__next__`, wie die offizielle Python-Dokumentation zu Generatoren zeigt.
Welche typischen Fehler solltest du vermeiden?
Fehler 1: Einen erschöpften Iterator erneut verwenden. Ein Iterator, der `StopIteration` geworfen hat, bleibt leer. Bei einer Liste in einer `for`-Schleife ist das kein Problem - `iter()` erzeugt bei jedem Schleifenstart einen frischen Iterator. Bei einem direkt verwendeten Iterator schon:
farben = iter(["rot", "gruen", "blau"])
liste1 = list(farben) # ['rot', 'gruen', 'blau']
liste2 = list(farben) # [] - der Iterator ist verbrauchtFehler 2: `__next__` gibt `None` statt Exception zurück. Wenn keine Elemente mehr da sind, *musst* du `raise StopIteration` schreiben. Die `for`-Schleife bricht sonst nie ab und `None` landet in deinen Daten.
Fehler 3: Zustand im Iterable statt im Iterator speichern. Wenn `__iter__()` `self` zurückgibt und der Index in derselben Klasse liegt, kannst du nicht zwei verschachtelte Schleifen über dasselbe Objekt laufen lassen. Beide teilen sich ja denselben Index.
Übungstipp: Bau dir einen eigenen Zähler
Nimm dir 20 Minuten und schreibe eine Klasse `Wochenende`, die über `for` nur `"Samstag"` und `"Sonntag"` ausgibt. Erweitere sie dann so, dass sie dreimal durchlaufen werden kann (Tipp: `__iter__` muss einen neuen Iterator zurückgeben). Schreibe den Code zuerst handschriftlich auf - das hilft dir beim Verinnerlichen der Syntax, gerade wenn eine Prüfung ansteht.
FAQ
Was ist der Unterschied zwischen Iterable und Iterator?
Ein Iterable implementiert `__iter__()` und kann durchlaufen werden. Ein Iterator implementiert zusätzlich `__next__()` und hält den aktuellen Zustand des Durchlaufs. `iter(liste)` liefert dir aus einem Iterable einen Iterator.
Wann sollte ich eine Iterator-Klasse statt einer Liste verwenden?
Wenn die Daten groß, unendlich oder teuer zu berechnen sind - oder wenn du einheitlichen Durchlauf-Code für verschiedene Datenquellen brauchst. Für 10 Elemente nimm einfach eine Liste.
Ist ein Generator dasselbe wie ein Iterator?
Fast. Ein Generator ist eine komfortable Art, einen Iterator zu erzeugen - mit `yield` und ohne eigene Klasse. Jeder Generator ist ein Iterator, aber nicht jeder Iterator ist ein Generator.
Warum wirft `__next__` eine StopIteration-Exception und gibt nicht einfach None zurück?
Weil `None` ein gültiger Wert in einer Sequenz sein könnte. Die Exception ist ein eindeutiges Signal: "Zu Ende" - und die `for`-Schleife weiß sofort, dass sie stoppen muss.
Fazit
Das Iterator Pattern in Python steckt in jeder `for`-Schleife, die du schreibst. Du weißt jetzt: Ein Iterable liefert über `__iter__()` einen Iterator, und der Iterator gibt über `__next__()` Elemente zurück, bis `StopIteration` fliegt. Mit eigenen Iterator-Klassen trennst du Durchlauf-Logik von Datenhaltung - und deine Objekte funktionieren automatisch mit allem, was Python an Iterations-Werkzeugen mitbringt. Für den Prüfungskontext (ob IHK-Abschlussprüfung, Uni-Klausur oder Vorstellungsgespräch) solltest du den Unterschied zwischen Iterable und Iterator sicher erklären können.
Wenn du bei Entwurfsmustern, OOP oder Python generell noch Unterstützung brauchst: Bei study-it.education findest du individuelle Nachhilfe genau für deinen Lernstand - ob Azubi, Student oder Berufseinsteiger. Schau vorbei und bring deine Python-Skills auf das nächste Level.
Want 1:1 help with this topic?
Need someone to walk through this with you?
Instead of re-reading: 30 min with a senior dev.
Book a free first chat →
Mit __iter__ und __next__ implementierst du das Iterator Pattern in Python – für sequenziellen Zugriff ohne interne Struktur offenzulegen.
marcel.schmidtpeter@study-it.education →More reading
Python HTTP requests senden: GET, POST & mehr mit requests
So sendest du mit der Python-Bibliothek requests GET- und POST-Anfragen an APIs – mit Beispielen für Azubis, Studenten und Berufseinsteiger.
Python JSON verarbeiten mit dem -Modul – einfach erklärt
JSON in Python lesen und schreiben? Das -Modul macht's einfach – von .loads bis .dumps, hier lernst du alles Wichtige.
Python Datenbank verbinden: sqlite3 & SQLAlchemy einfach erklärt
Erfahre, wie du Python per sqlite3 oder SQLAlchemy mit Datenbanken verbindest – mit Praxisbeispielen für Azubis, Studenten & Berufseinsteiger.