ProgrammatieBackend ontwikkelaar

Wat is een iterable object in Python en hoe implementeer je correct een gebruikersgedefinieerd iterabel object?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

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:

  • Iterabiliteit wordt gedefinieerd door de aanwezigheid van de methode __iter__.
  • Een iterator moet zowel __next__ als __iter__ implementeren (die self retourneert).
  • Het retourneren van een nieuw object in __iter__ is effectief als meerdere onafhankelijke doorlopen van de verzameling nodig zijn.

Misleidende vragen.

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)

Veelvoorkomende fouten en anti-patronen

  • Implementatie van alleen __next__ zonder __iter__ (of omgekeerd).
  • Het onthouden van de status op het klassenniveau in plaats van op het instantieniveau, wat leidt tot bugs bij herhaalde doorlopen.

Voorbeeld uit het leven

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:

  • Minder geheugen (slechts één index). Nadelen:
  • Fouten bij gelijktijdige iteratie met twee lussen.

Positieve case: Elke iterator bewaart zijn eigen status in de instantie die in __iter__ is aangemaakt. Voordelen:

  • Correcte werking van meerdere iterators. Nadelen:
  • Onbeduidend meer geheugenverbruik.