In großen Softwareprojekten ist es wichtig, Code so zu gestalten, dass er einfach wartbar ist und außerdem gewisse Funktionalitäten schnell gefunden werden können. Zusätzlich sollte er auch eine Struktur aufweisen, die es ermöglicht, eine bestimmte Funktion in einem großen Code mehrfach zu verwenden, anstatt sie jedes Mal neu zu schreiben. Die sogenannte Objektorientierte Programmierung ist dabei eine der besten Methoden, um Code zu organisieren und einfach zu strukturieren.
In der Programmiersprache Python werden dafür Objekte und Klassen verwendet, die den Aufbau eines Softwareprojektes deutlich vereinfachen und den Code besser strukturieren. In diesem Artikel schauen wir uns die Syntax dieser Bestandteile an und beschäftigen uns mit den grundlegenden Eigenschaften bis hin zu komplexeren Vorgängen wie der Vererbung oder dem Polymorphimus. Anhand von verständlichen Codebeispielen zeigen wir, wie einfach es sein kann, diese Ideen in Code einzubauen, um ihn weniger komplex zu machen und besser zu strukturieren.
Warum braucht man Klassen und Objekte?
Bei immer komplexer werdenden Softwareprojekten, welche häufig auch die Arbeit im Team erfordern, ist es wichtig, den Code so zu strukturieren, dass er einfach zu verstehen ist, leicht gewartet werden kann und außerdem effizient läuft. Mithilfe der sogenannten Objektorientierten Programmierung, die unter anderem in der Programmiersprache Python unterstützt wird, lassen sich komplexe Anwendungen in kleinere, logisch miteinander verbundene Teile unterteilen, an denen unabhängig voneinander gearbeitet werden kann. Solange die Ein- und Ausgaben einer Funktion identisch bleiben, fügt sich der Code nahtlos in die anderen Elemente mit ein und der Algorithmus kann einfach abgeändert werden.
In Python bieten Klassen und Objekte eine solide Grundlage, welche für die Objektorientierte Programmierung verwendet werden kann. Die Klasse kann man sich dabei wie einen Bauplan vorstellen, welcher die Eigenschaften und Verhaltensweise eines Objekts festlegt. Das Objekt hingegen ist dann eine konkrete Instanz, also eine Ausarbeitung dieses Bauplans. Die Klasse „Auto“ beispielsweise umfasst Eigenschaften, wie die Farbe, die Anzahl der Türen oder die Leistung des Motors. Ein spezifisches Auto hingegen ist ein Objekt, welches dann die Farbe Rot besitzt, vier Türen hat und eine Motorleistung von 200 PS aufweist.
Die Objektorientierte Programmierung bietet diverse Vorteile, wie zum Beispiel:
- Wiederverwendbarkeit: Eine definierte Klasse kann, nachdem sie einmal definiert wurde, beliebig oft innerhalb des Codes verwendet werden und außerdem auch um neue Attribute erweitert werden.
- Modularität: Durch die Unterteilung des Codes in verschiedene Objekte, können diese auch unabhängig voneinander getestet und bearbeitet werden. Dadurch wird beispielsweise die Weiterentwicklung vereinfacht, da diese an verschiedene Teammitarbeitende verteilt werden können.
- Bessere Wartbarkeit: Auch bei Erweiterungen kann der Code weiterhin einfach gepflegt werden und kann sogar durch neue Mitarbeitende schnell verstanden werden, da vorgegebene Strukturen und Beziehungen existieren.
- Erweiterbarkeit: Mithilfe von Vererbungen kann neuer Code auf bestehenden Klassen aufbauen, ohne dass der Originalcode verändert werden muss.
Klassen in Python
Ein Klasse in Python ist eine benutzerdefinierte Struktur, welche genutzt wird, um daraus konkrete Objekte zu erstellen und zu instanziieren. Darin werden zentral alle Funktionalitäten und Methoden hinterlegt, welche sich mit diesen Daten ausüben lassen. In den folgenden Abschnitten erläutern wir die grundlegende Syntax zur Erstellung und Nutzung von Klassen.
Wie erstellt man eine Klasse?
Um eine Klasse in Python erstellen zu können, verwendet man das Wort class
vor dem Namen der Klasse. Dieser Name wird typischer in der sogenannten Camel-Case Schreibweise definiert, welche sich dadurch auszeichnet, dass aufeinanderfolgende Wörter ohne Leerzeichen oder Unterstriche aneinandergereiht werden und dabei jedes neue Wort mit einem Großbuchstaben beginnen muss. Die darauffolgenden Buchstaben können entweder groß- oder kleingeschrieben sein. Das erste Wort kann dabei entweder mit einem Kleinbuchstaben beginnen, so wie beispielsweise bei “iPhone“, dann spricht man von lowerCaseCamel. Wenn hingegen das erste Wort auch mit einem Großbuchstaben beginnt, wie bei „PlayStation“, dann spricht man von UpperCamelCase.
Die Definition endet dann nach dem Namen der Klasse mit einem Doppelpunkt, woraufhin die nächste Zeile mit einer Einrückung startet und die eigentliche Logik enthält. In diesem einfachen Fall definieren wir nichts weiter als pass
, sodass die Klasse selbst keinen Code ausführt.

Im Normalfall beinhaltet eine Klasse verschiedene Attribute, welche die Eigenschaften festlegen und die Unterschiede zwischen den Objekten ausmachen. Dazu benötigen wir den __init__
Konstruktur, den wir uns im nächsten Abschnitt genauer anschauen.
Was sind Attribute und die Konstruktur-Methode __init__
?
Die __init__
Methode ist eine spezielle Methode in Python, welche aufgerufen wird, wenn ein Objekt aus einer Klasse instanziiert wird. Was das genau bedeutet, schauen wir uns zu einem späteren Zeitpunkt an. An dieser Stelle ist nur wichtig zu verstehen, dass __init__
einer Klasse verschiedene Attribute zuordnet und damit Anfangswerte definiert. Eine Person
kann beispielsweise einen Namen und ein Alter haben, welche als Attribute dargestellt, wie folgt aussehen:

Auf den ersten Blick mag das erstmal verwirrend aussehen, da man damit rechnen würde, dass hier bereits konkrete Werte zugeordnet werden und stattdessen nur name
und age
hinterlegt wurden. Deswegen sollten wir uns nochmals in Gedächtnis rufen, dass wir Klassen nutzen, um wiederverwendbaren Code zu erhalten und diesen zu modularisieren. Diese Zeilen bewirken, dass man die Klasse Person
nutzen kann, um verschiedene Personen mit unterschiedlichen Namen anlegen zu können. Dazu ruft man die Klasse auf und definiert in runden Klammern zwei konkrete Parameter für diese spezielle Person. Das Argument self
dient dabei als Referenz auf das aktuelle Objekt und ermöglicht den Zugriff auf die Attribute des Objektes. Mithilfe von dieser Logik können wir dann zum Beispiel die Person Alice definieren.

Durch Aufruf des Objektnamens und des Attributes getrennt durch einen Punkt können die konkreten Eigenschaften abgefragt werden. Dadurch erhalten wir dann zum Beispiel den Namen oder das Alter. Solche Attribute, welche innerhalb des __init__
Konstruktors definiert werden, nennt man Instanzattribute, da sie von Instanz zu Instanz unterschiedlich sind. Dem gegenüber stehen die Klassenattribute, welche für eine komplette Klasse gelten und somit auch für jede Instanz. Es kann über den Klassennamen oder über eine spezielle Instanz aufgerufen und darüber auch verändert werden.

Um mit diesen Attributen arbeiten zu können oder bestimmte Berechnungen durchführen zu können, werden die sogenannten Methoden benötigt.
Was sind Methoden?
Methoden sind Funktionen, welche innerhalb einer Klasse definiert wurden, um das Verhalten der Objekte zu bestimmen und mit den Attributen arbeiten zu können. Dabei haben sie nicht nur Zugriff auf die Instanzattribute, sondern können diese auch verändern und überschreiben. Die Besonderheit von jeder Methode ist, dass das erste Argument immer self
sein muss, um auf das entsprechende Objekt zuzugreifen, von dem es aufgerufen wird.

Die Methode introduce()
beispielsweise greift auf die beiden Attribute age
und name
zu und gibt diese als Zeichenkette zurück. Die Methode age_in_days()
geht sogar noch darüber hinaus und verändert das Attribut des Objekts, wenn sie aufgerufen wird. Nach dem Aufruf ist das Alter dann nicht mehr in Jahren, sondern in Tagen hinterlegt.
Objekte in Python
Objekte in Python sind Instanzen einer Klasse, welche konkrete Attribute enthalten und in einer Variablen abgespeichert sind. Bei der Arbeit mit Objekten ist es vor allem wichtig zu wissen, wie man diese erstellt, wie einzelne Attribute abgerufen und überschrieben werden können und wie man die Methoden nutzt.
Objekte erstellen
Wie wir in den vorherigen Abschnitten schon gesehen haben, können wir ein Objekt erstellen, indem wir eine Klasse definieren und diese dann aufrufen und die konkreten Attribute für das Objekt in runden Klammern übergeben, welche der __init__
Konstruktor benötigt. Dadurch wird das Objekt instanziiert und wir können im darauffolgenden Code mit der Instanz arbeiten.

Zugriff auf Attribute und Methoden
Nachdem ein Objekt instanziiert wurde, kann man auf die Attribute und Methode darin mithilfe des Operators zugreifen. Dafür nutzt man also den Namen des Objektes, einen Punkt und anschließend den Namen eines Attributs oder einer Methode. Diese kann man jedoch nicht nur lesen, sondern auch überschreiben oder verändern, um das Objekt zu verändern.

Im obigen Beispiel haben wir zuerst die Attribute von person1
abgerufen und anschließend das Alter auf 31 verändert und erneut abgerufen, um zu sehen, dass die Änderung funktioniert hat. Abschließend wurde noch die Methode introduce()
aufgerufen, um person1 vorzustellen.
Arbeit mit mehreren Objekten
Aus einer Klasse können viele verschiedene Objekte erstellt werden, die sich meist darin unterscheiden, dass sie unterschiedliche Attribute haben. Wichtig ist hierbei, dass eindeutige Variablennamen für die Instanzen genutzt werden, um sicherzustellen, dass sie eindeutig voneinander getrennt sind und sich nicht gegenseitig überschreiben.

In diesem Beispiel wird für jede Person eine eigenen Objektinstanz erstellt, mit den unterschiedlichen Attributen. Natürlich wäre es auch möglich zwei Instanzen zu haben, die dieselben Attribute aufweisen, also beispielsweise, wenn zwei Personen zufällig denselben Namen und dasselbe Alter haben. Dann ist es wichtig, die Variablennamen so zu definieren, dass die beiden Objekte voneinander getrennt werden können.
Was sind Methodenarten in Klassen?
In Python gibt es verschiedene Methodenarten, welche innerhalb einer Klasse genutzt werden können und abhängig von der Anwendung spezifische Aufgaben erfüllen. Jede dieser Methoden bietet verschiedene Vorteil, abhängig davon, ob sie auf die gesamte Klasse, eine einzelne Instanz oder unabhängig von beidem wirkt.
Instanzmethoden
Die Instanzmethoden sind die am häufigsten genutzt Methoden und wurden auch in diesem Artikel bereits mehrfach vorgestellt. Es handelt sich hierbei um Funktionen, die sich auf ein spezifisches Objekt der Klasse beziehen und beispielsweise Berechnungen mithilfe der konkreten Attribute durchführen. Sie zeichnen sich dadurch aus, dass der erste Parameter dieser Methode self
ist, wodurch die Methode in der Lage ist, auf Attribute und andere Methoden des Objekts zuzugreifen und diese auch zu bearbeiten.
Die Methode introduce()
ist ein klassisches Beispiel für eine Instanzmethode, welche die spezifischen Attribute für name
und age
verwendet, um daraus eine Zeichenkette zu bilden.

Klassenmethoden (@classmethod
)
Klassenmethoden beziehen sich auf die Klasse als Gesamtes und nicht auf einzelne Instanzen darin. Sie werden vor allem für Logiken genutzt, die für alle Instanzen einer Klasse gelten sollen, also zum Beispiel Regeln, welche bei der Erstellung neuer Instanzen Anwendung finden. Klassenmethoden werden mit dem Dekorator @classmethod
begonnen und haben als ersten Parameter cls
, welcher die Klasse selbst repräsentiert. Eine Klassenmethode kann genauso wie andere Methodenarten auch mit einem Punkt getrennt aufgerufen werden.

Die Klassenmethode from_birth_year()
ermöglicht es, dass neue Objekte auch dann erstellt werden können, wenn das konkrete Alter nicht bekannt ist, sondern lediglich das Geburtsjahr. Die Methode errechnet dann einfach das Alter und setzt es als Attribut für das Objekt. Dadurch bietet die Methode eine alternative Initialisierungsmöglichkeit.
Statische Methoden (@staticmethod
)
Statische Methoden unterscheiden sind von den vorherigen zwei Arten dadurch, dass sie unabhängig von konkreten Objekten oder Klassen sind und deshalb auch den self
oder cls
Parameter nicht benötigen. Sie eignen sich für Hilfsfunktionen, die nur lose mit der Klasse verbunden sind und keine Attribute oder andere Methoden benötigen, also in sich abgeschlossen sind.

In diesem Beispiel fügen wir die statische Methode add()
hinzu, die zwei beliebige, numerische Parameter zusammenaddieren kann und somit keinen Zugriff auf andere Parameter oder Methoden benötigt.
Wie funktioniert die Vererbung?
Ein zentrales Konzept der Objektorientierten Programmierung ist die sogenannte Vererbung, welche es ermöglicht, dass neue Klassen auf bestehenden Klassen aufbauen und deren Attribute und Methoden übernehmen. Dadurch wird die Wiederverwendbarkeit und Erweiterbarkeit von Code deutlich erhöht, indem spezialisierte Funktionalitäten nicht jedes Mal neu definiert werden müssen.
Die Basisklasse ist die Klasse von der andere Klassen Attribute und Methoden erben können. Sie kann normal definiert werden und beinhaltet keine besonderen Funktionalitäten. In unserem Beispiel wollen wir eine Basisklasse für Fahrzeuge erstellen und daraus dann neue Klassen für unterschiedliche Fahrzeugtypen, wie Autos oder Motorräder ableiten. Dazu definieren wir zuerst die Basisklasse.

Die daraus abgeleitete Klasse Car
wird so definiert, dass sie alle Methoden und Attribute von Vehicle erbt. Dazu wird bei der Definition die Basisklasse, also Vehicle
in Klammern definiert. Bei der Initialisierung wird die Funktion super()
verwendet, die anzeigt, dass die Attribute aus der Basisklasse übernommen werden und dadurch vermieden wird, dass diese neu definiert werden müssen. Außerdem kann super()
verwendet werden, um auf Methoden der Basisklasse zuzugreifen, wie zum Beispiel der Ausgabe .description()
, die dann in der abgeleiteten Klasse auch noch um weitere Attribute erweitert werden kann.

In diesem Beispiel findet außerdem eine Methodenüberschreibung statt, indem die Methode .description()
von der Basisklasse überschrieben wird und um weitere Attribute aus der Car
Klasse erweitert. Diese Funktionalität bietet sich vor allem an, wenn die Methode aus der Basisklasse nur einen allgemeinen Rahmen liefert und in der abgeleiteten Klasse, dann spezialisiertere Funktionalitäten benötigt werden.
Durch die Vererbung können verschiedene Codebestandteile wiederverwendet und erweitert werden. Dazu wird eine sehr allgemeine Basisklasse definiert auf der dann andere, abgeleitete Klassen aufbauen und weitere Attribute hinzufügen oder bestehende Methoden abändern können.
Was ist Polymorphismus?
Polymorphismus ist ein weiteres Konzept in der Objektorientierten Programmierung, welches ausdrückt, dass verschiedene Objekte aus unterschiedlichen Klassen über eine gemeinsame Schnittstelle angesprochen und bearbeitet werden können. Dadurch lässt sich eine Methode mit demselben Namen für verschiedene Klassen unterschiedlich implementieren und kann dann trotzdem über den identischen Namen aufgerufen werden.
In der Praxis werden dazu zwei verschiedene Konzepte verwendet:
- Methodenüberladung: Im Gegensatz zu anderen Programmiersprachen unterstützt Python keine klassische Methodenüberladung. Jedoch kann man mithilfe von flexiblen Parameterlisten in Methoden, beispielsweise durch die Nutzung von
*args
, vergleichbare Funktionalitäten erreichen. Dadurch können Methoden denselben Namen haben und trotzdem unterschiedliche Parameter entgegennehmen, abhängig davon, was das Objekt benötigt. - Methodenüberschreibung: Dies ist die häufigere Form in der Anwendung und beschreibt das Vorgehen, wenn eine abgeleitete Klasse eine Methode der Basisklasse überschreibt, um ein spezielleres Verhalten hervorzurufen, wie wir das im letzten Abschnitt für
.description()
gesehen haben. So kann dieselbe Methode abhängig vom Objekttyp angepasst werden.
In der Praxis wird Polymorphismus vor allem dann eingesetzt, wenn eine Funktion Objekte aus unterschiedlichen Klassen verwenden soll, ohne dabei die genauen Details kennen zu müssen. In dem folgenden Beispiel enthalten alle Klassen eine Methode speak()
, welche jedoch abhängig von der spezifischen Klasse unterschiedliche Ergebnisse haben kann. Die Funktion animal_speaks()
jedoch muss diese Unterschiede gar nicht kennen, da sie einfach die Methode über eine zentrale Schnittstelle aufrufen kann und abhängig davon, welches Objekt sie erhält, automatisch eine andere Ausgabe hat.

Durch den Polymorphismus ist es möglich, Code und Funktionen unabhängig vom Objekttyp flexibel und effizient zu gestalten und über eine einheitliche Schnittstelle arbeiten zu können.
Welche Spezialmethoden gibt es?
Spezialmethoden, oder magische Methoden, sind Methoden, welche spezielle Funktionen in Python bieten, indem sie es Klassen ermöglichen, bestimmte Operatoren und Funktionen zu nutzen. Sie beginnen und enden mit doppelten Unterstrichen („__“), weshalb sie auch Dunder-Methoden (Abkürzung für Double Under) genannt werden. Durch diese Methoden wird eine intuitive Interaktion mit den Methoden möglich und erleichtert dadurch die Erstellung benutzerdefinierter Klassen.
Einige magische Methoden, welche häufig verwendet werden, stellen wir im folgenden Abschnitt vor:
__str__
: Diese Methode wird aufgerufen, wenn eine lesbare und benutzerfreundliche Darstellung eines Objekts benötigt wird. Sie kann beispielsweise genutzt werden, um eine übersichtliche Darstellung der Attribute wiederzugeben. Wenn das Objekt dann mitprint()
aufgerufen wird, wird das wiedergegeben, was in__str__
definiert wurde.

__repr__
: Diese Methode ist ähnlich zu__str__
und soll verwendet werden, um eine möglichst unverwechselbare Repräsentation des Objekts zurückzugeben, die im besten Fall verwendet werden könnte, um das Objekt neu zu erstellen. Sie wird häufig dann genutzt, wenn man ein Objekt direkt in der Konsole anzeigen will. Sie kann außerhalb der Klasse einfach mithilfe vonrepr()
aufgerufen werden.

__add__
: Mithilfe von dieser Methode kann der+
Operator überladen werden, sodass eine neue Art und Weise der Addition für zwei Objekte der Klasse definiert wird. Wenn zwei Objekte der KlassePoint
addiert werden, sollen dann beispielsweise die beiden x-Koordinaten und die beiden y-Koordinaten miteinander addiert werden. Wenn dann der Operator+
für zwei Objekte aufgerufen wird, findet die Addition wie definiert statt. Wenn jedoch zwei andere Objekte, die nicht aus der Klasse stammen, mit+
addiert werden, dann erfolgt die Addition ganz normal.

__eq__
: Diese Methode überläd den Operator==
und definiert, wie zwei Objekte der Klasse miteinander verglichen werden sollen. Damit kann also überprüft werden, ob zwei Objekte identisch sind oder nicht. Analog zu__add__
hat dies jedoch keine Auswirkungen auf Vergleiche zwischen zwei Objekten, die nicht Instanzen der Klasse sind.

__len__
: Diese magische Methode ermöglicht die Definition einer eigenen Logik für die Bestimmung der Länge eines Objekts der Klasse. In unserem Beispiel von einem Punkt im zweidimensionalen Raum kann die Länge beispielsweise so definiert werden, dass sie die Länge des Vektors zurückgibt, der vom Ursprung zu diesem Punkt führt. Dazu wird der Satz des Pythagoras hinterlegt. Da die Methodelen()
nur Ganzzahlen zurückgeben kann, müssen wir die Länge entsprechend in eine Ganzzahl verwandeln und verlieren dadurch etwas an Genauigkeit.

Die Spezialmethoden ermöglichen es, den Umgang mit Objekten und Klassen intuitiver zu gestalten, indem gängige Operatoren, wie +
oder len()
mit neuen Funktionalitäten überladen werden, die jedoch nur für die Instanzen der Klasse gelten und ansonsten ihre gewohnte Funktionalität behalten.
Das solltest Du mitnehmen
- Die Objektorientierte Programmierung ist ein zentrales Konzept, welches zu einem besser strukturierten und wiederverwendbaren Code führt.
- In Python dienen Objekte und Klassen dazu, dass die Objektorientierte Programmierung implementiert werden kann.
- Klassen sind allgemeine Konzepte und Baupläne, die als Grundlage dienen, um daraus spezielle Objekte zu instanziieren, die dann konkrete Attribute besitzen.
- Methoden wiederum sind spezielle Funktionalitäten, welche Berechnungen innerhalb der Klasse durchführen. Hierbei unterscheidet man Instanzmethoden, welche auf konkrete Attribute des Objekts zurückgreifen, Klassenmethoden, die für eine gesamte Klasse definiert werden, und statische Methoden, die komplett losgelöst von der Klasse agieren können.
- Die Vererbung ermöglicht es, dass Klassen gewisse Methoden und Attribute von einer Basisklasse übernehmen können, ohne dass diese neu definiert werden müssen.
- Mithilfe von Spezialmethoden kann die Arbeit mit Klassen deutlich intuitiver gestaltet werden, da gängige Operatoren und deren Funktionalität für Objekte einer Klasse überladen werden.
Was ist Jenkins?
Jenkins beherrschen: Rationalisieren Sie DevOps mit leistungsstarker Automatisierung. Lernen Sie CI/CD-Konzepte und deren Umsetzung.
Python-Tutorial: Bedingte Anweisungen und If/Else Blöcke
Lernen Sie, wie man bedingte Anweisungen in Python verwendet. Verstehen Sie if-else und verschachtelte if- und elif-Anweisungen.
Was ist XOR?
Entdecken Sie XOR: Die Rolle des Exklusiv-Oder-Operators in Logik, Verschlüsselung, Mathematik, KI und Technologie.
Wie kannst Du die Ausnahmebehandlung in Python umsetzen?
Die Kunst der Ausnahmebehandlung in Python: Best Practices, Tipps und die wichtigsten Unterschiede zwischen Python 2 und Python 3.
Was sind Python Module?
Erforschen Sie Python Module: Verstehen Sie ihre Rolle, verbessern Sie die Funktionalität und rationalisieren Sie die Programmierung.
Was sind Python Vergleichsoperatoren?
Beherrschen Sie die Python Vergleichsoperatoren für präzise Logik und Entscheidungsfindung beim Programmieren in Python.
Andere Beiträge zum Thema Klassen und Objekte in Python
Dieser Link führt Dich zu meiner Deepnote-App, in der Du den gesamten Code findest, den ich in diesem Artikel verwendet habe, und ihn selbst ausführen kannst.

Niklas Lang
Seit 2020 bin ich als Machine Learning Engineer und Softwareentwickler tätig und beschäftige mich leidenschaftlich mit der Welt der Daten, Algorithmen und Softwareentwicklung. Neben meiner Arbeit in der Praxis unterrichte ich an mehreren deutschen Hochschulen, darunter die IU International University of Applied Sciences und die Duale Hochschule Baden-Württemberg, in den Bereichen Data Science, Mathematik und Business Analytics.
Mein Ziel ist es, komplexe Themen wie Statistik und maschinelles Lernen so aufzubereiten, dass sie nicht nur verständlich, sondern auch spannend und greifbar werden. Dabei kombiniere ich praktische Erfahrungen aus der Industrie mit fundierten theoretischen Grundlagen, um meine Studierenden bestmöglich auf die Herausforderungen der Datenwelt vorzubereiten.