Een klassendecorator is een functie die een klasse als argument accepteert en een gemodificeerde of volledig nieuwe klasse retourneert. Hiermee kunnen we dynamisch methoden toevoegen, het gedrag van bestaande methoden wijzigen of zelfs een subklasse retourneren die de functionaliteit van de oorspronkelijke klasse uitbreidt.
def add_repr(cls): def __repr__(self): return f'<{cls.__name__}: {self.__dict__}>' cls.__repr__ = __repr__ return cls @add_repr class Point: def __init__(self, x, y): self.x = x self.y = y p = Point(3, 4) print(p) # <Point: {'x': 3, 'y': 4}>
add_repr voegt dynamisch de methode __repr__ toe aan alle klassen waaraan deze is toegepast.*args en **kwargs niet ondersteunt die worden gebruikt bij het creëren van exemplaren van de klasse.Wat gebeurt er als we twee klassendecorators achter elkaar toepassen? Is de volgorde van toepassing altijd duidelijk?
Decorators worden "van onder naar boven" toegepast: eerst wordt de decorator die zich direct boven de klasseverklaring bevindt toegepast, dan de volgende er boven en zo verder. De volgorde is ZEER BELANGRIJK, omdat het resultaat van de eerste decorator naar de tweede wordt doorgegeven en zo verder.
@dec1 @dec2 class Test: ... # Dit is gelijk aan: # Test = dec1(dec2(Test))
Verhaal
In een e-commerce applicatie wilden ze methoden van de klasse loggen, maar per ongeluk retourneerden ze het verkeerde object uit de decorator, waardoor de methoden hun klasse-eigenschap verloren en niet meer correct werden geërfd, wat leidde tot het breken van het model.
Verhaal
In een project voor het automatisch genereren van nieuwe methoden gebruikten ze een toevoeg-decorator, maar vergaten super() te gebruiken bij het retourneren van de subklasse. Dit leidde tot een verstoring van de hiërarchie en MRO, wat resulteerde in niet-werkende aanroepen van de basisklasse in de afgeleiden.
Verhaal
In een data-pijplijn probeerden ze klassen te wikkelen met meerdere decorators (logger, tracker van wijzigingen), maar door een onjuiste volgorde van toepassing kregen ze een naamconflict van methoden, wat leidde tot fouten in de productie door "verloren" methoden.