Python-klassen en -objecten: de zelfstudie van 2026
De meeste Python OOP-tutorials leren de syntaxis en slaan het mentale model over. Deze doet het tegenovergestelde: je krijgt een duidelijk beeld van wat een klasse is tijdens runtime, wanneer je naar @dataclass moet grijpen in plaats van __init__ met de hand te schrijven, en hoe self echt werkt (het is geen magie).
We behandelen: de minimaal levensvatbare klasse van vier regels, waarom self een parameter is, kenmerken van klasse versus instantie (de nr. 1 beginnersbug), de zes dunder-methoden die je overal tegenkomt, @dataclass als de moderne standaard, en een harde regel voor wanneer je klassen met rust moet laten en een gewone functie moet gebruiken.
Het mentale model: een klas is een fabriek
Een klasse in Python is een fabriek die objecten produceert. Elke keer dat u Rect(3, 4) aanroept, maakt Python een nieuw object met zijn eigen opslag en geeft dit aan u terug.
Dat is de hele monteur. De klasse is de blauwdruk; elke Rect(...)-aanroep is een stempel van de blauwdruk in nieuw RAM-geheugen.
self is slechts een parameter
De grootste verwarring voor mensen die van JS of Ruby komen: self in Python is expliciet. De eerste parameter van elke methode is een verwijzing naar de instantie die wordt aangeroepen.
Dus c.bump() is syntactische suiker voor Counter.bump(c). Python geeft de instantie door als het eerste arg. Je zou het 'ik', 'dit' of 'foo' kunnen noemen - 'zelf' is een conventie, geen trefwoord. Blijf bij self (PEP 8), zodat andere Python-ontwikkelaars uw code kunnen lezen.
De class vs instance attribuut trap
De meest voorkomende Python OOP-bug in een codebase voor beginners:
items = [] bij klassebereik creëert EEN lijst die door elke instantie wordt gedeeld. a.add("milk") muteert het, dus b.items ziet dezelfde lijst.
Regel: initialiseer de veranderlijke status in `__init__`, niet in het klassenbereik.
Deze bug is vaker in productie genomen dan welke Python-ontwikkelaar dan ook zal toegeven. Let op lijsten, dictaten, sets met klassenbereik.
De zes methoden die je overal ziet
Dunder-methoden (__name__) zijn Python's operator-hooks voor overbelasting. Deze zes dekken 95% van wat je tegenkomt:
1. __init__(self, ...) — constructor
Wordt uitgevoerd wanneer het object wordt gemaakt. Stel hier instantiekenmerken in. Retourneer niets (Python dwingt 'None' af).
2. __repr__(self) — tekenreeks voor ontwikkelaars
Aangeroepen door print(x) als __str__ ontbreekt, en altijd door de REPL. Streef naar iets dat je terug in Python zou kunnen plakken om het object opnieuw te maken:
3. __eq__(zelf, ander) — gelijkheid
Zonder dit retourneert Rect(3, 4) == Rect(3, 4) False (standaard is identiteit). Veld voor veld vergelijken:
4. __hash__(self) — hasheerbaarheid
Als je __eq__ overschrijft, MOET je ook __hash__ overschrijven, anders stelt Python __hash__ = Geen in (object wordt niet-hashbaar). Het eenvoudigste: return hash((self.width, self.height)).
5. __len__(self) — voor len(obj)
Zorgt ervoor dat len(cart) == 5 werkt.
6. __iter__(self) — voor voor x in obj:
Retourneer een iterator. yield inside maakt de klasse itereerbaar:
@dataclass — de moderne standaard
Als uw klasse voornamelijk uit gegevenshouder bestaat (drie velden, een __init__, een __repr__, een __eq__), stop dan met het schrijven van die standaardtekst. @dataclass genereert het allemaal op basis van uw typeannotaties:
Dat zijn __init__, __repr__ en __eq__, allemaal gegenereerd. Voeg @dataclass(frozen=True) toe om het object onveranderlijk te maken EN krijg __hash__ gratis.
Regel: bereik eerst `@dataclass`. Schrijf alleen een handgerolde klasse als u methoden nodig heeft die geen attribuutaccessoire zijn.
__slots__ — geheugenoptimalisatie (geavanceerd)
Standaard heeft elke instance een __dict__, zodat u willekeurige attributen kunt toevoegen. __slots__ swaps die een vaste structuur op C-niveau vereisen - kleinere RAM-voetafdruk en snellere toegang tot attributen:
Gebruik __slots__ wanneer: (a) u miljoenen instances aan het maken bent en RAM belangrijk is, of (b) u typfouten in de attribuuttoewijzing tijdens runtime wilt onderscheppen. Sla het anders over: het schakelt augurk standaard uit en verbreekt meervoudige overerving op subtiele manieren.
Wanneer moet je de lessen met rust laten?
Harde regel: als uw klasse EEN methode plus `__init__` heeft, zou het waarschijnlijk een functie moeten zijn.
Klassen verdienen hun gewicht wanneer ze state behouden bij meerdere methodeaanroepen, of wanneer ze een goed gedefinieerd protocol implementeren (__iter__, __enter__, __eq__, etc.). One-shot-logica is een functie.
Erfenis — gebruik het spaarzaam
Erfenis is reëel, maar wordt te veel gebruikt. In 2026 geeft Python de voorkeur aan composition – houd een ander object als attribuut vast in plaats van ervan te erven:
Erf alleen als u een echte 'is-een'-relatie heeft EN u gedrag wilt overschrijven. Een NamedRect die overerft van Rect om een name-veld toe te voegen is prima. Het bouwen van een overervingshiërarchie van vijf niveaus voor een klasse bedrijfslogica is code die u in zes maanden zult ontwarren.
Klassen zijn een van de krachtigste functies van Python en een van de gemakkelijkst te gebruiken functies. Het mentale model dat helpt: een klasse is een fabriek voor objecten, self is een gewone parameter, de veranderlijke status gaat naar __init__, reik eerst naar @dataclass en ga terug naar een functie wanneer de klasse minder dan twee statusdragende methoden heeft.
Volgende stap: 30 praktische OOP-lessen over klassen, @dataclass, overerving versus compositie en de dunder-methoden — waarbij echte Python in uw browser draait en bij elke stap een AI-mentor.