EMZETT.
Login

Kurz: Bisher hast du Daten (Variablen) und Funktionen getrennt behandelt. Bei der objektorientierten Programmierung (OOP) fasst du beides zusammen: Ein Objekt hat Eigenschaften (Daten) und Fähigkeiten (Funktionen).

Teil des Kurses Python

Kapitel 36 von 44 im Kurs Python (Abschnitt „Objektorientierung“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Bisher hast du Daten (Variablen) und Funktionen getrennt behandelt. Bei der objektorientierten Programmierung (OOP) fasst du beides zusammen: Ein Objekt hat Eigenschaften (Daten) und Fähigkeiten (Funktionen). Die Bauanleitung dafür heißt Klasse.

Du kennst Objekte schon: Ein str ist ein Objekt mit Methoden wie .upper(), eine list eins mit .append().

Eine Klasse definieren

class Hund:
    def __init__(self, name, alter):
        self.name = name
        self.alter = alter
 
    def bellen(self):
        return f"{self.name} sagt: Wuff!"
 
rex = Hund("Rex", 3)
mimi = Hund("Mimi", 5)
print(rex.name, rex.alter)
print(rex.bellen())
print(mimi.bellen())
print(type(rex))

Ausgabe:

Rex 3
Rex sagt: Wuff!
Mimi sagt: Wuff!
<class '__main__.Hund'>

Was hier passiert:

  • class Hund: legt die Klasse an (Namen schreibt man in CamelCase).
  • __init__ ist der Konstruktor: Er läuft automatisch, wenn du Hund(...) aufrufst, und setzt die Anfangswerte.
  • self ist das Objekt selbst. Es steht in jeder Methode als erster Parameter, beim Aufruf übergibt Python es automatisch.
  • self.name = name speichert einen Wert als Attribut des Objekts.
  • rex und mimi sind zwei unabhängige Instanzen derselben Klasse.

Attribute ändern

class Konto:
    def __init__(self, inhaber, stand=0):
        self.inhaber = inhaber
        self.stand = stand
 
    def einzahlen(self, betrag):
        self.stand += betrag
 
    def abheben(self, betrag):
        if betrag > self.stand:
            raise ValueError("Nicht genug Guthaben")
        self.stand -= betrag
 
k = Konto("Mia", 100)
k.einzahlen(50)
k.abheben(30)
print(k.stand)
try:
    k.abheben(1000)
except ValueError as e:
    print("Fehler:", e)

Ausgabe:

120
Fehler: Nicht genug Guthaben

Klassenattribute

Ein Attribut, das direkt in der Klasse steht, gehört allen Instanzen gemeinsam:

class Zaehler:
    anzahl = 0               # Klassenattribut
 
    def __init__(self):
        Zaehler.anzahl += 1
 
Zaehler()
Zaehler()
c = Zaehler()
print(Zaehler.anzahl, c.anzahl)

Ausgabe:

3 3

Lesbare Ausgabe mit str und repr

Ohne Hilfe zeigt print(objekt) nur eine Speicheradresse. Mit __str__ bestimmst du den Text für Menschen, mit __repr__ die eindeutige Darstellung für Entwickler:

class Punkt:
    def __init__(self, x, y):
        self.x, self.y = x, y
 
    def __str__(self):
        return f"({self.x}|{self.y})"
 
    def __repr__(self):
        return f"Punkt({self.x}, {self.y})"
 
p = Punkt(2, 5)
print(p)
print([p, Punkt(0, 0)])
print(repr(p))

Ausgabe:

(2|5)
[Punkt(2, 5), Punkt(0, 0)]
Punkt(2, 5)

Kapselung und Konventionen

Python kennt kein striktes private. Stattdessen gibt es Konventionen:

SchreibweiseBedeutung
nameöffentlich
_name”intern”, bitte nicht von außen anfassen
__namewird umbenannt (name mangling), schützt vor versehentlichem Überschreiben in Unterklassen

Methodenarten

class Kreis:
    PI = 3.14159
 
    def __init__(self, r):
        self.r = r
 
    def flaeche(self):                 # normale Methode (braucht self)
        return Kreis.PI * self.r ** 2
 
    @classmethod
    def aus_durchmesser(cls, d):       # alternativer Konstruktor
        return cls(d / 2)
 
    @staticmethod
    def ist_gueltig(r):                # braucht weder self noch cls
        return r > 0
 
k = Kreis.aus_durchmesser(10)
print(k.r, round(k.flaeche(), 2), Kreis.ist_gueltig(-1))

Ausgabe:

5.0 78.54 False

Merke

  • Eine Klasse ist eine Bauanleitung, ein Objekt (Instanz) ein daraus gebautes Exemplar
  • __init__ setzt die Anfangswerte, self ist das aktuelle Objekt
  • Attribute speichern Daten, Methoden sind Funktionen der Klasse
  • __str__ für Menschen, __repr__ für Entwickler
  • @classmethod und @staticmethod für Methoden ohne Instanz
  • _name bedeutet “intern” (nur Konvention)

Übungsaufgabe

Schreibe eine Klasse Rechteck mit Breite und Höhe, einer Methode flaeche() und einer Methode umfang().

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Reguläre Ausdrücke

Weiter: Vererbung und Polymorphie

Alle Kapitel: Python im Überblick