Geschiedenis van de vraag:
Sequences zijn een van de oudste en meest basale concepten in Python. Klassieke voorbeelden zijn lijsten (list), strings (str), en tuples (tuple). Voor interactie met sequences is er een speciaal protocol geïdentificeerd: de methoden __getitem__ en __len__ moeten worden geïmplementeerd. Dit stelt het object in staat om zich "als een sequence" te gedragen - ondersteuning van indexering, slices, gebruik in loops en zelfs sommige standaardfuncties.
Probleem:
Zonder de juiste implementatie van deze methoden kan een gebruikersklasse niet werken met indexeringsoperaties, for-loops, functies zoals len(). Vaak implementeren beginnende ontwikkelaars slechts een van de methoden, negeren ze uitzonderinghandling, implementeren ze geen ondersteuning voor slices, en ondervinden ze onjuiste of onverwachte gedragingen.
Oplossing:
Je moet de methode __getitem__(self, key) implementeren voor ondersteuning van indexering en slices, en daarnaast __len__(self) voor gebruik met de functie len() en correcte iterabiliteit. Voor ondersteuning van slices moet je het type key in __getitem__ onderscheiden en correct omgaan met slice-objecten.
Voorbeeldcode:
def is_even(n): return n % 2 == 0 class EvenSequence: def __init__(self, size): self.size = size def __getitem__(self, index): if isinstance(index, slice): return [x for x in range(self.size)[index] if is_even(x)] if index < 0 or index >= self.size: raise IndexError('Index out of bounds') return index if is_even(index) else None def __len__(self): return self.size
Belangrijke kenmerken:
Kun je je alleen beperken tot de methode getitem, zodat het object als een sequence werkt?
Deels. Als je alleen __getitem__ implementeert, kun je itereren over het object met for en elementen indexeren, maar len() zal niet werken.
Voorbeeldcode:
class SeqOnlyGetitem: def __getitem__(self, index): if index >= 10: raise IndexError return index * 2 s = SeqOnlyGetitem() for x in s: print(x) # Werkt (iterable) # print(len(s)) # TypeError
Hoe om te gaan met negatieve indexen en wat gebeurt er als je ze niet in overweging neemt?
Negatieve indexen zijn een sleutelkenmerk van sequences in Python. Als je ze niet afhandelt, gedraagt het object zich op een onverwachte manier voor de gebruiker.
class NegIndex: def __init__(self, data): self.data = data def __getitem__(self, index): if index < 0: index += len(self.data) return self.data[index]
Moet je contains of iter implementeren voor je Sequence-klasse?
Niet noodzakelijk. Als __getitem__ en __len__ zijn geïmplementeerd, zal de functie in werken, en for zal deze gebruiken voor iteratie. De implementatie van deze methoden is meestal niet nodig, maar kan de prestaties verbeteren.
Een ontwikkelaar implementeerde alleen getitem voor zijn klasse alleen voor positieve indexen. De module doorstond enkele unittests, maar bij daadwerkelijk gebruik faalde het bij het proberen om een niet-bestaande index of negatieve index te verkrijgen.
Voordelen:
Nadelen:
Het team implementeerde beide methoden (getitem en len), hield rekening met slices, negatieve indexen, en gooide correcte uitzonderingen. De eindklasse functioneerde in alle standaardgevallen van Python.
Voordelen:
Nadelen: