Weiter zum Inhalt

Einführung in Python-Metaklassen

In diesem Tutorial lernst du, was Metaklassen sind, wie du sie in Python implementierst und wie du eigene erstellst.
Aktualisiert 18. Sept. 2026  · 6 Min. lesen

Mit KI erkunden

ChatGPTClaudePerplexity

Eine Metaklasse in Python ist die Klasse einer Klasse und legt fest, wie sich eine Klasse verhält. Eine Klasse ist selbst eine Instanz einer Metaklasse. Eine Klasse in Python bestimmt, wie sich ihre Instanzen verhalten. Um Metaklassen wirklich zu verstehen, solltest du bereits mit Python-Klassen gearbeitet haben. Bevor wir tiefer einsteigen, räumen wir ein paar Grundbegriffe aus dem Weg.

Alles in Python ist ein Objekt

class TestClass():
    pass

my_test_class = TestClass()
print(my_test_class)
<__main__.TestClass object at 0x7f6fcc6bf908>

Python-Klassen lassen sich dynamisch erzeugen

type in Python erlaubt es uns, den Typ eines Objekts zu ermitteln. Schauen wir uns den Typ des oben erzeugten Objekts an.

type(TestClass)
type
type(type)
type

Moment, was ist da passiert? Wir würden erwarten, dass der Typ des oben erstellten Objekts „class“ ist – ist er aber nicht. Behalte den Gedanken kurz im Hinterkopf, wir kommen gleich darauf zurück. Außerdem sehen wir, dass der Typ von type selbst type ist. Es ist also eine Instanz von type. Ein weiterer „magischer“ Trick von type ist, dass wir damit Klassen dynamisch erzeugen können. Unten zeigen wir, wie das geht. Die Klasse DataCamp unten ließe sich mit type wie folgt erzeugen:

class DataCamp():
    pass
DataCampClass = type('DataCamp', (), {})
print(DataCampClass)
print(DataCamp())
<class '__main__.DataCamp'>
<__main__.DataCamp object at 0x7f6fcc66e358>

Im obigen Beispiel ist DataCamp der Klassenname, während DataCampClass die Variablenreferenz auf die Klasse ist. Beim Einsatz von type können wir Attribute über ein Dictionary übergeben, wie hier gezeigt:

PythonClass = type('PythonClass', (), {'start_date': 'August 2018', 'instructor': 'John Doe'} )
print(PythonClass.start_date, PythonClass.instructor)
print(PythonClass)
August 2018 John Doe
<class '__main__.PythonClass'>

Wenn unsere PythonClass von der Klasse DataCamp erben soll, übergeben wir sie als zweites Argument bei der Definition mit type:

PythonClass = type('PythonClass', (DataCamp,), {'start_date': 'August 2018', 'instructor': 'John Doe'} )
print(PythonClass)
<class '__main__.PythonClass'>

Nachdem diese zwei Konzepte geklärt sind, erkennen wir: Python erstellt Klassen mithilfe einer Metaklasse. Wir haben gesehen, dass alles in Python ein Objekt ist – und diese Objekte werden von Metaklassen erzeugt. Immer wenn wir mit class eine Klasse definieren, erzeugt im Hintergrund eine Metaklasse diese Klasse. Wir haben oben bereits gesehen, wie type das praktisch übernimmt. Das ist vergleichbar mit str für Strings und int für Ganzzahlen. In Python erlaubt uns das Attribut ___class__, den Typ der aktuellen Instanz zu prüfen. Erstellen wir unten einen String und prüfen seinen Typ.

article = 'metaclasses'
article.__class__
str

Wir können den Typ auch mit type(article) prüfen.

type(article)
str

Wenn wir den Typ von str prüfen, stellen wir ebenfalls fest, dass er type ist.

type(str)
type

Prüfen wir den Typ von float, int, list, tuple und dict, erhalten wir ein ähnliches Ergebnis. Das liegt daran, dass all diese Objekte vom Typ type sind.

print(type(list),type(float), type(dict), type(tuple))
<class 'type'> <class 'type'> <class 'type'> <class 'type'>

Wir haben bereits gesehen, dass type Klassen erzeugt. Wenn wir also __class__ von __class__ prüfen, sollte type zurückgegeben werden.

article.__class__.__class__
type

Meistere deine Datenkenntnisse mit DataCamp

Mehr als 10 Millionen Menschen lernen Python, R, SQL und andere technische Fertigkeiten in unseren praxisorientierten Kursen, die von Branchenexperten entwickelt wurden.

Lernen Beginnen
learner-on-couch@2x.jpg

Eigene Metaklassen erstellen

In Python können wir den Prozess der Klassenerzeugung anpassen, indem wir das Schlüsselwort metaclass in der Klassendefinition verwenden. Das funktioniert auch, indem wir von einer Klasse erben, die dieses Schlüsselwort bereits gesetzt hat.

class MyMeta(type):
    pass

class MyClass(metaclass=MyMeta):
    pass

class MySubclass(MyClass):
    pass

Unten sehen wir, dass der Typ der Klasse MyMeta type ist und dass der Typ von MyClass und MySubClass MyMeta ist.

print(type(MyMeta))
print(type(MyClass))
print(type(MySubclass))
<class 'type'>
<class '__main__.MyMeta'>
<class '__main__.MyMeta'>

Wird eine Klasse ohne Metaklasse definiert, verwendet Python standardmäßig die Metaklasse type. Wenn eine Metaklasse angegeben ist und sie keine Instanz von type() ist, wird sie direkt als Metaklasse verwendet.

__new__ und __init__

Metaklassen können auf zwei Arten wie unten gezeigt definiert werden. Den Unterschied erklären wir im Anschluss.

class MetaOne(type):
    def __new__(cls, name, bases, dict):
        pass

class MetaTwo(type):
    def __init__(self, name, bases, dict):
        pass

__new__ wird genutzt, wenn man dict oder das bases-Tuple festlegen möchte, bevor die Klasse erzeugt wird. Der Rückgabewert von __new__ ist üblicherweise eine Instanz von cls. __new__ erlaubt Unterklassen unveränderlicher Typen, die Instanzerzeugung anzupassen. In benutzerdefinierten Metaklassen kann es überschrieben werden, um die Klassenerzeugung zu steuern. __init__ wird in der Regel aufgerufen, nachdem das Objekt erstellt wurde, um es zu initialisieren.

Metaklassen-Methode __call__

Laut der offiziellen Dokumentation können wir auch andere Klassenmethoden überschreiben, indem wir in der Metaklasse eine eigene __call__()-Methode definieren, die benutzerdefiniertes Verhalten beim Aufruf der Klasse ermöglicht.

Metaklassen-Methode __prepare__

Nach Pythons Data-Model-Dokumentation

Sobald die passende Metaklasse ermittelt wurde, wird der Klassen-Namespace vorbereitet. Wenn die Metaklasse ein Attribut __prepare__ hat, wird es wie folgt aufgerufen: namespace = metaclass.__prepare__(name, bases, **kwds) (weitere Schlüsselwortargumente stammen aus der Klassendefinition). Hat die Metaklasse kein __prepare__-Attribut, wird der Klassen-Namespace als leeres geordnetes Mapping initialisiert. - docs.python.org

Singleton-Pattern mit einer Metaklasse

Dieses Entwurfsmuster beschränkt die Instanziierung einer Klasse auf genau ein Objekt. Das ist zum Beispiel nützlich, wenn du eine Klasse für die Datenbankverbindung entwickelst und nur eine einzige Instanz dieser Verbindungsklasse haben möchtest.

class SingletonMeta(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(SingletonMeta,cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class SingletonClass(metaclass=SingletonMeta):
    pass

Fazit

In diesem Artikel hast du gelernt, was Metaklassen sind und wie wir sie in Python einsetzen können. Metaklassen lassen sich unter anderem für Logging, die Registrierung von Klassen zur Erzeugungszeit oder für Profiling nutzen. Sie wirken recht abstrakt, und vielleicht fragst du dich, ob du sie überhaupt brauchst. Python-Veteran Tim Peters beantwortet das am treffendsten.

"Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why).” - realpython

Wenn du mehr über Python lernen möchtest, starte den Python Programming-Lernpfad von DataCamp und lies unser Python Classes Tutorial.

Link eins

Link zwei

Themen
Python

Python-Kurse

Kurs

Einführung in Python

4 Std.
7M
Lerne in nur vier Stunden die Grundlagen der Datenanalyse mit Python und entdecke beliebte Python-Pakete.
Details anzeigenRight Arrow
Kurs Starten
Mehr anzeigenRight Arrow