ProgrammatieSoftware Engineer

Hoe werken klasse-eigenschappen (class properties) in Python? Wat is het verschil tussen property en gewone attributen, hoe implementeer je een berekende eigenschap, en waarom is het belangrijk om toezicht te houden op de getter/setter functies?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Eigenschappen (property) in Python zijn ontstaan als een elegante manier om de encapsulatie van attributen te implementeren, vergelijkbaar met getters en setters uit andere talen (Java/C++), maar zonder dat het nodig is om expliciet methoden aan te roepen. Voor property moest toegang tot variabelen worden geïmplementeerd via expliciete get/set methoden, wat de interface van de klasse bemoeilijkte en vervuilde.

Het probleem is dat de gebruiker van de klasse een transparante interface voor werken met attributen moet hebben (met behulp van dot-notatie obj.x), terwijl we onder de motorkap de logica voor berekening, controle, caching of validatie van waarden konden beheren. Zonder property moet je bij wijzigingen van de interne implementatie alle aanroepen wijzigen, wat leidt tot massale fouten en een vermindering van de uitbreidbaarheid.

De oplossing is de decorator @property, die een methode in een attribuut kan veranderen en tegelijkertijd de logica voor berekening, controle of lazy loading binnen de methoden kan verbergen, zonder de externe interface van de klasse te wijzigen. De getter is alleen leesbaar, met behulp van .setter organiseren we de schrijfoperatie, en .deleter — de verwijdering.

Codevoorbeeld:

class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): # 'area' kan nu worden gelezen als attribuut return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): # wordt automatisch aangeroepen bij toewijzing rect.width = ... assert value > 0, "Width must be positive" self._width = value rect = Rectangle(3, 4) print(rect.area) # 12 rect.width = 10 print(rect.area) # 40

Belangrijke kenmerken:

  • Eigenschappen verbergen berekeningen of controles onder normaal toegang tot een attribuut.
  • property ondersteunt getter, setter, deleter.
  • Het gebruik van property vereist geen wijziging van de gebruikerscode bij wijziging van de implementatie.

Lastige vragen.

Kan property werken met class-methoden of statische methoden?

Nee. property doet alleen instance-level (exemplaar) eigenschappen. Voor class-level gebruik je speciale descriptormen of @classmethod-property (handmatig geïmplementeerd).

Als je property alleen met getter zonder setter declareert, is het dan mogelijk om in het attribuut te schrijven?

Nee. Deze property is alleen-lezen; een poging tot toewijzing zal AttributeError veroorzaken.

Wat gebeurt er als er een uitzondering optreedt binnen de setter (bijvoorbeeld assert)?

De uitzondering wordt omhoog gegooid, de toewijzing vindt niet plaats en de waarde van het attribuut blijft ongewijzigd. Dit wordt vaak gebruikt voor validatie.

Veelvoorkomende fouten en anti-patronen

  • Geen gebruik maken van beschermde (_attr) of privé (__attr) attributen in de backend van property — dit kan leiden tot recursieve verwijzingen naar self.attr.
  • Gebruik van property zonder noodzaak (daar waar er geen berekeningen of controles zijn).
  • Ontbrekende validatie in de setter, wat leidt tot het breken van klasse-invarianten.

Voorbeeld uit het leven

Negatieve case: Publieke klasse-attributen, wijzigingen zonder controle.
Voordelen: snel, eenvoudig.
Nadelen: geen interne logica veranderen zonder de clientcode te herschrijven, mogelijk onverenigbare toestanden.

Positieve case: Encapsulatie via property, logica in getter/setter, strikte controles.
Voordelen: flexibiliteit, controle, transparantie, veilige evolutie van de API.
Nadelen: iets meer code, kleine complicatie tijdens het debuggen.