Metaclasses in Python zijn klassen die andere klassen creëren. Als een klasse een sjabloon is voor objecten, dan is een metaklasse een sjabloon voor het maken van klassen. Hiermee kun je programmatically definiëren hoe klassen worden gemaakt en gewijzigd.
In Python is alles een object, inclusief klassen. Dit stelt je in staat om de logica van het creëren, wijzigen en controleren van klassen in de fase van hun generatie te definiëren. Dergelijke mechanismen zijn al in andere talen gebruikt, maar in Python zijn ze bijzonder eenvoudig en elegant geïmplementeerd via het mechanisme van metaclasses.
Soms moeten in grote projecten klassen volgens speciale regels worden opgebouwd of noodzakelijke methoden, eigenschappen bevatten, of automatisch worden gewijzigd bij hun definitie. Zonder metaclasses zou dit leiden tot code duplicatie en verspreiding van fouten.
Metaclasses stellen je in staat om het creëren van klassen te wijzigen door de methoden van de type klasse te overschrijven, bijvoorbeeld new en init. Je kunt automatisch methoden en eigenschappen toevoegen, de structuur valideren, reflectie toepassen.
class UpperAttrMeta(type): def __new__(cls, name, bases, dct): new_attrs = {} for key, value in dct.items(): if not key.startswith('__'): new_attrs[key.upper()] = value else: new_attrs[key] = value return super().__new__(cls, name, bases, new_attrs) class Foo(metaclass=UpperAttrMeta): bar = 'bip' print(hasattr(Foo, 'bar')) # False print(hasattr(Foo, 'BAR')) # True
metaclass in de klassedefinitieKan de metaklasse van een exemplaar worden gewijzigd na het creëren van de klasse? Nee. Na het maken van een klasse kan de metaklasse niet worden gewijzigd zonder de klasse opnieuw te genereren. Een exemplaar gebruikt de metaklasse die voor zijn klasse is gedefinieerd.
Hoe verschillen metaclasses van klasse-decorators? Klasse-decorators kunnen de klasse wijzigen na het creëren ervan, terwijl metaclasses het proces van creatie zelf beheren en zelfs het creëren van de klasse kunnen verbieden of de basis klassen kunnen wijzigen.
Moet elke klasse een eigen metaklasse hebben?
Nee. Gewoonlijk wordt de standaard type gebruikt, een metaklasse is alleen nodig wanneer je het standaardgedrag wilt doorbreken.
Voordelen:
Negatieve case: Een beginnende architect begon met metaclasses voor eenvoudige taken te gebruiken (bijvoorbeeld, automatische generatie van str), in plaats van decorators. Voordelen: hij leerde een nieuw instrument. Nadelen: hij belastte het team met onnodige magie, er ontstonden bugs.
Positieve case: In een complexe ORM werd een metaklasse gebruikt voor de automatische generatie van tabellen op basis van Python-classes. Voordelen: gecentraliseerde controle van de structuur, automatische bijwerking van mappings. Nadelen: gedetailleerde documentatie en training van nieuwe teamleden waren vereist.