In Python stelt de decorator @property je in staat om "virtuele" attributen te creëren - methoden die eruitzien en gebruikt worden als gewone velden, maar de logica van de getter, setter of deleter uitvoeren. Dit is handig voor het creëren van berekende eigenschappen of het beheersen van de toegang tot gegevens.
Voorbeeld:
class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): if value <= 0: raise ValueError('Width must be positive') self._width = value r = Rectangle(3, 4) print(r.area) # 12 (wordt opgeroepen als een eigenschap, geen functie) r.width = 10 # setter wordt automatisch aangeroepen
Kan je alleen één @property (get-methode) gebruiken zonder een setter te definiëren? Wat gebeurt er als je probeert deze attribuut te wijzigen?
Antwoord: Je kunt alleen de getter @property zonder setter (of deleter) definiëren. Zo'n attribuut zal read-only zijn, en een toewijzing zal AttributeError veroorzaken.
class C: @property def x(self): return 42 c = C() c.x = 99 # AttributeError: kan attribuut niet instellen
Verhaal
We probeerden een object te serialiseren met de standaardbibliotheek, gebruikmakend van vars(obj) om de woordenlijst van attributen te krijgen. Het bleek dat property-methoden niet in de uitvoer van __dict__ zaten, waardoor hun waarden niet werden geserialiseerd, wat leidde tot gegevenslekken.
Verhaal
In het project vergaten we een setter toe te voegen voor de property, wat resulteerde in een fout tijdens runtime bij het proberen de waarde van het berekende veld te veranderen, hoewel dit volgens de architectuur logisch was.
Verhaal
In de werkende code vereiste de berekening van de waarde van de property zware of onveilige bewerkingen, die onverwacht werden uitgevoerd bij elke toegang tot de eigenschap. Dit verlaagde de prestaties en leidde tot blokkeringen in de multithread-code.