Achtergrond van de vraag: Het concept van iterabiliteit is in Python ontstaan om te uniformeren met betrekking tot verzameling: lijst, woordenboek, set, enz. Elk object dat je kunt itereren met een for-lus wordt als iterabel beschouwd. Dit is gerealiseerd door middel van bepaalde magische methoden.
Probleem: Python vereist bepaalde protocollen voor een correcte werking van lussen en functies die verband houden met sequenties. Als een gebruiker deze protocollen niet correct in zijn klasse implementeert, zullen de standaardmechanismen (for, list(), sum(), enz.) niet werken of zich onverwacht gedragen.
Oplossing:
Een object is iterabel als het de methode __iter__ implementeert. Een iterator is iemand die de methode __next__ en __iter__ heeft, die self retourneert. Gewoonlijk is het object dat door __iter__ wordt geretourneerd een iterator, maar dat is niet noodzakelijk. Voorbeeld:
class MyRange: def __init__(self, start, end): self.start = start self.end = end def __iter__(self): self.current = self.start return self def __next__(self): if self.current < self.end: val = self.current self.current += 1 return val raise StopIteration for x in MyRange(1, 4): print(x) # 1, 2, 3
Kernkenmerken:
__iter__.__next__ als __iter__ implementeren (die self retourneert).__iter__ is effectief als meerdere onafhankelijke doorlopen van de verzameling nodig zijn.Is de methode next vereist voor elk iterabel object?
Nee. Voor een iterabel object is alleen __iter__ vereist, dat een iterator retourneert. __next__ is alleen van toepassing op de iterator zelf. Bijvoorbeeld, een list heeft geen __next__ methode, maar is iterabel: zijn __iter__ retourneert een instantie van een iterator.
lst = [1, 2, 3] print(hasattr(lst, '__next__')) # False
Kan een object op zich een iterator zijn?
Ja, als het beide methoden — zowel __iter__ als __next__ — implementeert.
Kun je meerdere iterators met een onafhankelijke status voor één verzameling maken?
Ja, als __iter__ elke keer een nieuw iterator object retourneert.
class MyList: def __init__(self, data): self.data = data def __iter__(self): return iter(self.data)
__next__ zonder __iter__ (of omgekeerd).Negatieve case: De iterator-klasse bewaart de status (bijvoorbeeld de huidige index) op klasse-niveau in plaats van op instantieniveau, waardoor parallelle iteraties elkaar verstoren. Voordelen:
Positieve case:
Elke iterator bewaart zijn eigen status in de instantie die in __iter__ is aangemaakt.
Voordelen: