Python-Klassen und -Objekte: Das Tutorial 2026
Die meisten Python-OOP-Tutorials vermitteln die Syntax und überspringen das mentale Modell. Dies bewirkt das Gegenteil – Sie erhalten ein klares Bild davon, was eine Klasse zur Laufzeit ist, wann Sie nach „@dataclass“ greifen sollten, anstatt „__init__“ von Hand zu schreiben, und wie „self“ wirklich funktioniert (es ist keine Zauberei).
Wir behandeln Folgendes: die vierzeilige minimal lebensfähige Klasse, warum „self“ ein Parameter ist, Klassen- und Instanzattribute (der Anfängerfehler Nr. 1), die sechs Dunder-Methoden, die Sie überall sehen werden, „@dataclass“ als moderne Standardeinstellung und eine strenge Regel, wann Klassen in Ruhe gelassen und eine einfache Funktion verwendet werden sollten.
Das mentale Modell: Eine Klasse ist eine Fabrik
Eine Klasse in Python ist eine Fabrik, die Objekte produziert. Jedes Mal, wenn Sie „Rect(3, 4)“ aufrufen, erstellt Python ein neues Objekt mit eigenem Speicher und gibt es an Sie zurück.
Das ist die gesamte Mechanik. Die Klasse ist die Blaupause; Jeder „Rect(...)“-Aufruf ist ein Stempel des Bauplans in den neuen RAM.
„self“ ist nur ein Parameter
Die größte Verwirrung für Leute, die von JS oder Ruby kommen: „self“ in Python ist explizit. Der erste Parameter jeder Methode ist eine Referenz auf die aufgerufene Instanz.
„c.bump()“ ist also syntaktischer Zucker für „Counter.bump(c)“. Python übergibt die Instanz als erstes Argument. Man könnte es „me“, „this“ oder „foo“ nennen – „self“ ist eine Konvention, kein Schlüsselwort. Bleiben Sie bei „self“ (PEP 8), damit andere Python-Entwickler Ihren Code lesen können.
Die Klasse-gegen-Instanz-Attributfalle
Der häufigste Python-OOP-Fehler in einer Codebasis für Anfänger:
„items = []“ im Klassenbereich erstellt EINE Liste, die von jeder Instanz gemeinsam genutzt wird. „a.add("milk")` mutiert es, sodass „b.items“ dieselbe Liste sieht.
Regel: Initialisiere den veränderlichen Zustand in „__init__“, nicht im Klassenbereich.
Dieser Fehler wurde öfter in die Produktion übertragen, als jeder Python-Entwickler zugeben würde. Achten Sie auf Listen, Diktate und Mengen im Klassenbereich.
Die sechs Methoden, die Sie überall sehen werden
Dunder-Methoden („__name__“) sind Pythons Operator-Überladungs-Hooks. Diese sechs decken 95 % dessen ab, was Ihnen begegnen wird:
1. __init__(self, ...) – Konstruktor
Wird ausgeführt, wenn das Objekt erstellt wird. Legen Sie hier Instanzattribute fest. Nichts zurückgeben (Python erzwingt „Keine“).
2. „__repr__(self)“ – entwicklerorientierte Zeichenfolge
Wird von „print(x)“ aufgerufen, wenn „__str__“ fehlt, und immer von der REPL. Suchen Sie nach etwas, das Sie wieder in Python einfügen können, um das Objekt neu zu erstellen:
3. „__eq__(self, other)“ – Gleichheit
Ohne sie gibt „Rect(3, 4) == Rect(3, 4)“ „False“ zurück (Standard ist Identität). Feld für Feld vergleichen:
4. „__hash__(self)“ – Hashfähigkeit
Wenn Sie „__eq__“ überschreiben, MÜSSEN Sie auch „__hash__“ überschreiben, oder Python legt „__hash__ = None“ fest (das Objekt wird nicht mehr hashbar). Am einfachsten: „return hash((self.width, self.height))“.
5. „__len__(self)“ – für „len(obj)“.
Lässt len(cart) == 5 funktionieren.
6. __iter__(self) – für for x in obj:
Gibt einen Iterator zurück. „yield“ im Inneren macht die Klasse iterierbar:
„@dataclass“ – der moderne Standard
Wenn Ihre Klasse hauptsächlich ein Datenbehälter ist (drei Felder, ein „__init__“, ein „__repr__“, ein „__eq__“), hören Sie auf, dieses Boilerplate zu schreiben. „@dataclass“ generiert alles aus Ihren Typanmerkungen:
Das sind „__init__“, „__repr__“ und „__eq__“, die alle generiert wurden. Fügen Sie „@dataclass(frozen=True)“ hinzu, um das Objekt unveränderlich zu machen UND „__hash__“ frei zu bekommen.
Regel: Greifen Sie zuerst nach „@dataclass“. Schreiben Sie eine handgerollte Klasse nur, wenn Sie Methoden benötigen, die keine Attributzugriffsfunktionen sind.
__slots__ – Speicheroptimierung (erweitert)
Standardmäßig trägt jede Instanz ein „__dict__“, sodass Sie beliebige Attribute hinzufügen können. „__slots__“ tauscht dieses Diktat gegen eine feste C-Level-Struktur aus – kleinerer RAM-Fußabdruck und schnellerer Attributzugriff:
Verwenden Sie „__slots__“, wenn: (a) Sie Millionen von Instanzen erstellen und RAM wichtig ist, oder (b) Sie Tippfehler bei der Attributzuweisung zur Laufzeit abfangen möchten. Andernfalls überspringen Sie es – es deaktiviert pickle standardmäßig und unterbricht die Mehrfachvererbung auf subtile Weise.
Wann man den Unterricht in Ruhe lassen sollte
Harte Regel: Wenn Ihre Klasse EINE Methode plus „__init__“ hat, sollte es wahrscheinlich eine Funktion sein.
Klassen erhalten ihr Gewicht, wenn sie über mehrere Methodenaufrufe hinweg state halten oder wenn sie ein genau definiertes Protokoll implementieren (__iter__, __enter__, __eq__ usw.). One-Shot-Logik ist eine Funktion.
Vererbung – gehen Sie sparsam damit um
Vererbung ist real, wird aber überstrapaziert. Bevorzugen Sie in Python 2026 Komposition – halten Sie ein anderes Objekt als Attribut, anstatt von ihm zu erben:
Erben Sie nur, wenn Sie eine echte „Ist-ein“-Beziehung haben UND Sie Ihr Verhalten überschreiben möchten. Ein „NamedRect“, das von „Rect“ erbt, um ein „Name“-Feld hinzuzufügen, ist in Ordnung. Der Aufbau einer fünfstufigen Vererbungshierarchie für eine Geschäftslogikklasse ist ein Code, den Sie in sechs Monaten entwirren werden.
Klassen gehören zu den leistungsstärksten Funktionen von Python und lassen sich am einfachsten überbeanspruchen. Das mentale Modell, das hilft: Eine Klasse ist eine Fabrik für Objekte, „self“ ist ein einfacher Parameter, der veränderliche Zustand geht in „__init__“, greifen Sie zuerst nach „@dataclass“ und kehren Sie zu einer Funktion zurück, wenn die Klasse weniger als zwei zustandstragende Methoden hat.
Nächster Schritt: 30 praktische OOP-Lektionen zu Klassen, „@dataclass“, Vererbung vs. Komposition und den Dunder-Methoden – mit echtem Python in Ihrem Browser und einem KI-Mentor bei jedem Schritt.