Home

Anhang 0 Teil 2: Einführung in die Programmierung mit Python

appendix python programming oop functions classes beginners

Neu im Terminal? Lesen Sie zuerst Anhang 0 Teil 1: Terminal- und CLI-Grundlagen. Dieser Anhang setzt voraus, dass Sie ein Terminal öffnen und Befehle ausführen können.

Dies ist der zweite Teil des Vorab-Kursmaterials. Teil 1 hat Ihnen beigebracht, wie Sie über ein Terminal mit Ihrem Computer kommunizieren. Jetzt beantworten wir eine größere Frage: Warum sollten Sie das überhaupt wollen?

Am Ende dieses Anhangs werden Sie:

Dies ist Vorab-Lektüre für den Kurs. Arbeiten Sie es in Ihrem eigenen Tempo durch. Sie müssen keine Syntax auswendig lernen – das Ziel ist, ein Gespür dafür zu entwickeln, wie Programmierer denken.


Warum schreiben Menschen Programme?

Jede Software, die Sie jemals benutzt haben, existiert, weil jemand ein Problem hatte und beschloss, es mit Code zu lösen.

Denken Sie an die Anwendungen auf Ihrem Smartphone. Instagram existiert, weil Kevin Systrom eine einfache Möglichkeit wollte, Fotos mit Filtern zu teilen. Spotify existiert, weil Daniel Ek Musik ohne Piraterie zugänglich machen wollte. Google existiert, weil Larry Page und Sergey Brin relevante Informationen in einem wachsenden Ozean von Webseiten finden wollten. Netflix begann mit dem Versand von DVDs, schrieb dann aber Software, die Filme besser empfehlen konnte als jeder menschliche Verkäufer.

Das sind alles Probleme, die mit Programmen gelöst wurden.

Aber Software besteht nicht nur aus Consumer-Apps. Programmierung ist überall:

Der gemeinsame Nenner? Jemand hatte ein Problem. Code war das Werkzeug, um es zu lösen.

Von großen Ideen zu kleinen Schritten

Natürlich können Sie sich nicht am ersten Tag hinsetzen und Netflix bauen. Die Ingenieure bei Netflix haben auch nicht dort angefangen – sie begannen mit denselben Grundlagen, die Sie gleich lernen werden.

Der Trick beim Programmierenlernen besteht darin, Probleme zu finden, die klein genug sind, um sie heute zu lösen, aber bedeutsam genug, um sich dafür zu interessieren. Hello World auf den Bildschirm zu schreiben lehrt Sie fast nichts, weil es kein echtes Problem löst. Aber Temperaturen umrechnen, Daten analysieren oder Statistiken berechnen – das sind echte Aufgaben, die echtes Denken erfordern.

In diesem gesamten Anhang arbeiten wir mit einem einzigen durchgehenden Beispiel: einer Wetterstation. Jeder versteht Wetter. Es beinhaltet Zahlen (Temperaturen, Luftfeuchtigkeit, Windgeschwindigkeit), Text (Städtenamen, Beschreibungen) und logische Entscheidungen (Regnet es?). Es ist einfach genug zum Anfangen, aber reichhaltig genug, um zu zeigen, warum jedes neue Programmierkonzept wichtig ist.

Fangen wir an.


Warum Python?

Es gibt Hunderte von Programmiersprachen. Warum verwendet dieser Kurs Python?

Drei Gründe:

1. Kein Kompilierungsschritt. In vielen Sprachen (C, Java, Rust) schreiben Sie Code, führen dann ein separates Programm namens Compiler aus, das ihn in etwas übersetzt, das der Computer ausführen kann, und erst dann können Sie ihn starten. Python überspringt den mittleren Schritt. Sie schreiben Code und führen ihn sofort aus. Das macht Experimentieren schnell und unkompliziert.

Sprache Schritt 1 Schritt 2 Schritt 3
C main.c schreiben Kompilieren: gcc main.c -o main Ausführen: ./main
Java Main.java schreiben Kompilieren: javac Main.java Ausführen: java Main
Python main.py schreiben Ausführen: python main.py

2. Für schnelles Prototyping entwickelt. Guido van Rossum schuf Python 1991 mit einer Philosophie: Code soll leicht zu lesen, leicht zu schreiben und schnell von einer Idee in ein funktionierendes Programm umzusetzen sein. Python wurde für Menschen gebaut, nicht für Maschinen.

3. Die Sprache der Wissenschaft und KI. Heute ist Python die dominierende Sprache in Data Science, Machine Learning, wissenschaftlichem Rechnen und Automatisierung. Bibliotheken wie NumPy, Pandas, TensorFlow und PyTorch sind alle Python-first. Wenn Sie in irgendeinem Bereich mit Daten oder KI arbeiten, werden Sie Python begegnen.

Hier ist Ihr erstes Python-Programm. Öffnen Sie ein Terminal (Sie haben in Teil 1 gelernt, wie das geht), erstellen Sie eine Datei namens hello.py und führen Sie sie aus:

# save this as hello.py
print("Hello from Python!")
$ python hello.py
Hello from Python!

Das war’s. Kein Compiler. Kein Build-Schritt. Schreiben, ausführen, Ergebnis sehen.


Elementare Datentypen und Berechnungen

Jedes Problem, das Sie mit Code lösen möchten, erfordert irgendeine Form von Berechnung. Programmiersprachen geben Ihnen grundlegende Bausteine, um Daten darzustellen und zu verarbeiten – Zahlen, Text und logische Werte. Wenn Sie jemals Mathematik gemacht haben, verstehen Sie diese Konzepte bereits.

Zahlen und Strings: Die Bausteine

In der Mathematik arbeiten Sie mit ganzen Zahlen (1, 2, 3) und reellen Zahlen (3,14; 2,718). In Python heißen diese int und float:

temperature_celsius = 23.5      # float (Dezimalzahl)
number_of_sensors = 4            # int (Ganzzahl)
city = "Aalen"                   # str (Text, ein sogenannter "String")
is_raining = False               # bool (True oder False)

Eine Variable ist einfach ein Name, der an einen Wert gebunden ist – stellen Sie es sich wie eine beschriftete Box vor. Sie wählen den Namen, Python merkt sich den Wert.

Beachten Sie print() – Sie verwenden es seit Ihrem allerersten hello.py und haben vielleicht nicht weiter darüber nachgedacht. print() ist eine eingebaute Funktion (Built-in Function), die Python Ihnen kostenlos zur Verfügung stellt. Sie übergeben ihr einen Wert, und sie zeigt diesen Wert auf dem Bildschirm an. Sie müssen nicht verstehen, wie sie intern funktioniert – nur dass sie etwas entgegennimmt und sichtbar macht. In Abschnitt 4 werden Sie lernen, eigene Funktionen zu schreiben. Wenn Sie dort ankommen, werden Sie feststellen, dass Sie bereits seit Ihrer ersten Codezeile eine Funktion aufgerufen haben.

Sie können Python auch fragen, welchen Typ ein Wert hat, indem Sie print() mit einer weiteren eingebauten Funktion, type(), kombinieren:

print(type(temperature_celsius))   # <class 'float'>
print(type(number_of_sensors))     # <class 'int'>
print(type(city))                  # <class 'str'>
print(type(is_raining))            # <class 'bool'>

Das ist alles, was Sie jetzt über Typen wissen müssen. Es gibt vier grundlegende:

Typ Was er darstellt Beispiele
int Ganzzahlen 0, 42, -7
float Dezimalzahlen 3.14, -0.5, 23.5
str Text (Zeichenketten) "Aalen", "hello", "42"
bool Logische Werte True, False

Operatoren: Mathematik mit Code

Sie kennen Arithmetik. Python auch:

celsius = 23.5

# The classic conversion formula
fahrenheit = celsius * 9 / 5 + 32

print(fahrenheit)   # 74.3

Die arithmetischen Operatoren funktionieren genau so, wie Sie es erwarten:

a = 10
b = 3

print(a + b)    # 13    Addition
print(a - b)    # 7     Subtraktion
print(a * b)    # 30    Multiplikation
print(a / b)    # 3.33  Division (gibt immer float zurück)
print(a // b)   # 3     Ganzzahldivision (rundet ab)
print(a % b)    # 1     Modulo (Rest)
print(a ** b)   # 1000  Potenzierung (10 hoch 3)

Sie können auch Werte vergleichen – das Ergebnis ist immer ein bool:

temperature = 23.5

print(temperature > 30)     # False
print(temperature < 0)      # False
print(temperature == 23.5)  # True
print(temperature >= 20)    # True

Mit nur Variablen und Operatoren können Sie bereits nützliche Arbeit leisten. Rechnen wir eine Temperatur um:

# Weather station in Aalen reads 23.5 degrees Celsius
celsius_aalen = 23.5
fahrenheit_aalen = celsius_aalen * 9 / 5 + 32
print("Aalen:", fahrenheit_aalen, "F")   # Aalen: 74.3 F

Sammlungen: Listen

In der realen Welt haben Sie selten nur einen einzelnen Wert. Eine Wetterstation zeichnet stündlich Temperaturen auf. Sie brauchen eine Möglichkeit, mehrere Werte zusammen zu speichern.

Eine Liste ist eine geordnete Folge von Werten:

# Daily temperatures for one week in Aalen (Celsius)
daily_temps = [18.2, 21.0, 19.5, 23.5, 25.1, 22.8, 20.3]

print(daily_temps[0])       # 18.2  (erstes Element, Zählung beginnt bei 0)
print(daily_temps[3])       # 23.5  (viertes Element)
print(len(daily_temps))     # 7     (Anzahl der Elemente)

Sie können eine Liste durchlaufen, um jedes Element zu verarbeiten:

# Compute the average temperature
total = 0
for temp in daily_temps:
    total = total + temp

average = total / len(daily_temps)
print("Average:", average)   # Average: 21.485714285714288

Listen sind mächtig, aber sie sind nur Container. Wenn Ihr Code wächst, werden Sie mehr Struktur benötigen. Sehen wir uns an, warum.

Das Problem: Wiederholung

Angenommen, Sie überwachen fünf Städte. Sie müssen jede Temperatur in Fahrenheit umrechnen:

# Five cities, five conversions
celsius_aalen = 23.5
fahrenheit_aalen = celsius_aalen * 9 / 5 + 32

celsius_berlin = 19.0
fahrenheit_berlin = celsius_berlin * 9 / 5 + 32

celsius_munich = 21.3
fahrenheit_munich = celsius_munich * 9 / 5 + 32

celsius_stuttgart = 20.7
fahrenheit_stuttgart = celsius_stuttgart * 9 / 5 + 32

celsius_hamburg = 16.8
fahrenheit_hamburg = celsius_hamburg * 9 / 5 + 32

Das funktioniert. Aber schauen Sie sich die Wiederholung an. Dieselbe Formel erscheint fünfmal. Stellen Sie sich nun vor:

Code per Copy-Paste zu vervielfältigen ist ein Rezept für Fehler. Es muss einen besseren Weg geben.

Probieren Sie es jetzt aus: Öffnen Sie das Guided Hands-On Notebook (Abschnitt 1-2) und:

  1. Erstellen Sie eine Variable celsius mit der heutigen ungefähren Temperatur
  2. Rechnen Sie sie mit der Formel in Fahrenheit um: fahrenheit = celsius * 9 / 5 + 32
  3. Erstellen Sie eine Liste mit fünf Temperaturen und berechnen Sie deren Durchschnitt mit einer Schleife

Funktionen: Wiederverwendung statt Wiederholung

Sie kennen Funktionen bereits aus dem Mathematikunterricht. Wenn Ihr Dozent geschrieben hat:

\(f(x) = x \cdot \frac{9}{5} + 32\)

würden Sie sofort verstehen: Geben Sie mir einen beliebigen Wert von \(x\), und ich gebe das Ergebnis dieser Formel zurück. Sie schreiben die Formel nicht jedes Mal neu – Sie rufen einfach \(f(23.5)\) auf und erhalten 74,3.

Python-Funktionen funktionieren genauso.

Von Mathematik zu Code

Hier ist die Temperaturumrechnung als Python-Funktion:

def celsius_to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32

Das war’s. def bedeutet “definiere eine Funktion”. Der Name ist celsius_to_fahrenheit. Sie nimmt eine Eingabe (celsius) und gibt eine Ausgabe zurück. Nun wird das Fünf-Städte-Problem zu:

def celsius_to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32

print("Aalen:", celsius_to_fahrenheit(23.5))       # 74.3
print("Berlin:", celsius_to_fahrenheit(19.0))       # 66.2
print("Munich:", celsius_to_fahrenheit(21.3))       # 70.34
print("Stuttgart:", celsius_to_fahrenheit(20.7))    # 69.26
print("Hamburg:", celsius_to_fahrenheit(16.8))       # 62.24

Die Formel existiert einmal. Wenn Sie sie ändern müssen, ändern Sie sie an einer Stelle. Wenn Sie 100 Städte haben, rufen Sie die Funktion einfach 100 Mal auf.

Noch besser – kombinieren Sie es mit einer Liste:

cities = [
    ["Aalen", 23.5],
    ["Berlin", 19.0],
    ["Munich", 21.3],
    ["Stuttgart", 20.7],
    ["Hamburg", 16.8],
]

for city_data in cities:
    print(city_data[0] + ":", celsius_to_fahrenheit(city_data[1]))

Fünf Städte oder fünftausend – der Code bleibt gleich lang.

Funktionen mit mehreren Ein- und Ausgaben

Funktionen können mehrere Parameter entgegennehmen und mehrere Werte zurückgeben:

def analyze_temperatures(readings):
    """Analyze a list of temperature readings."""
    min_val = min(readings)
    max_val = max(readings)
    avg_val = sum(readings) / len(readings)
    return min_val, max_val, avg_val

daily_temps = [18.2, 21.0, 19.5, 23.5, 25.1, 22.8, 20.3]

lowest, highest, average = analyze_temperatures(daily_temps)
print("Lowest:", lowest)     # 18.2
print("Highest:", highest)   # 25.1
print("Average:", average)   # 21.49

Funktionen sind ein enormer Fortschritt. Sie eliminieren Wiederholungen und machen Ihren Code lesbar. Aber wenn Probleme wachsen, reichen Funktionen allein nicht aus.

Das Problem: Zu viele lose Werte

Ihre Wetterstation erfasst mehr als nur die Temperatur. Sie zeichnet auch Luftfeuchtigkeit, Windgeschwindigkeit, den Städtenamen und einen Zeitstempel auf. Nun braucht Ihre Funktion all diese Werte:

def report_weather(city, temperature, humidity, wind_speed, timestamp):
    fahrenheit = celsius_to_fahrenheit(temperature)
    print(city, "at", timestamp)
    print("  Temperature:", temperature, "C /", fahrenheit, "F")
    print("  Humidity:", humidity, "%")
    print("  Wind:", wind_speed, "km/h")

def feels_like(temperature, humidity, wind_speed):
    # simplified wind chill calculation
    return temperature - (wind_speed * 0.7)

# Calling these functions requires passing the same values over and over
report_weather("Aalen", 23.5, 65.0, 12.3, "2026-03-11 14:00")
wind_chill = feels_like(23.5, 65.0, 12.3)

Sehen Sie das Problem? Die Werte 23.5, 65.0, 12.3 gehören zusammen – sie sind alle Teil derselben Wettermessung. Aber wir reichen sie als separate, lose Werte herum. Was, wenn Sie versehentlich Luftfeuchtigkeit und Windgeschwindigkeit vertauschen? Python wird sich nicht beschweren. Ihre Ergebnisse werden einfach falsch sein.

Wenn Sie dieselbe Gruppe von Werten an mehrere Funktionen übergeben, verlangen diese Werte danach, zusammengefasst zu werden.

Passing loose values
temperature
humidity
wind_speed
city
timestamp
▼▼▼▼▼
report_weather(city, temperature, humidity, wind_speed, timestamp)
▶ much cleaner
Passing one object
WeatherReading
temperature humidity wind_speed city timestamp
▼
report_weather(reading)

Probieren Sie es jetzt aus (Notebook Abschnitt 3):

  1. Schreiben Sie eine Funktion celsius_to_fahrenheit(celsius), die Celsius in Fahrenheit umrechnet
  2. Schreiben Sie eine Funktion feels_like(temp, humidity, wind), die temp - (wind * 0.7) zurückgibt
  3. Rufen Sie beide Funktionen für drei verschiedene Städte auf
  4. Beachten Sie, wie viele Argumente Sie jedes Mal wiederholen

Stellen Sie sich eine Klasse als leeres Formular vor – eine Vorlage mit beschrifteten Feldern. Ein “Wettermessungs-Formular” hat Felder für Temperatur, Luftfeuchtigkeit, Windgeschwindigkeit und Städtename. Jedes Mal, wenn Sie eines dieser Formulare ausfüllen, erstellen Sie eine Instanz – eine konkrete Messung mit konkreten Werten.

In Python definieren Sie das Formular (die Klasse) einmal und erstellen dann so viele ausgefüllte Kopien (Instanzen), wie Sie benötigen.

Ihre erste Klasse

class WeatherReading:
    def __init__(self, city, temperature, humidity, wind_speed):
        self.city = city
        self.temperature = temperature
        self.humidity = humidity
        self.wind_speed = wind_speed

Lassen Sie uns das aufschlüsseln:

Erstellen Sie nun Instanzen:

aalen = WeatherReading("Aalen", 23.5, 65.0, 12.3)
berlin = WeatherReading("Berlin", 19.0, 72.0, 8.5)
munich = WeatherReading("Munich", 21.3, 58.0, 15.1)

# Access individual fields with dot notation
print(aalen.city)          # Aalen
print(aalen.temperature)   # 23.5
print(berlin.humidity)     # 72.0

Die Daten, die zusammengehören, leben jetzt zusammen in einem Objekt.

Klassen als Funktionsparameter

Erinnern Sie sich an die unübersichtliche Funktion mit fünf Parametern? Mit einer Klasse wird sie sauber:

# Before: five separate parameters
def report_weather(city, temperature, humidity, wind_speed, timestamp):
    ...

# After: one object that carries everything
def report_weather(reading):
    fahrenheit = celsius_to_fahrenheit(reading.temperature)
    print(reading.city)
    print("  Temperature:", reading.temperature, "C /", fahrenheit, "F")
    print("  Humidity:", reading.humidity, "%")
    print("  Wind:", reading.wind_speed, "km/h")

report_weather(aalen)   # clean, readable, no chance of swapping values

Ein Parameter statt fünf. Kein Risiko, Luftfeuchtigkeit und Windgeschwindigkeit zu vertauschen. Und wenn Sie später ein pressure-Feld zu WeatherReading hinzufügen, müssen Sie die Funktionssignatur überhaupt nicht ändern.

Das Problem: Funktionen leben getrennt von ihren Daten

Wir haben jetzt eine WeatherReading-Klasse und eigenständige Funktionen wie celsius_to_fahrenheit und feels_like. Aber celsius_to_fahrenheit macht nur im Kontext einer Wettermessung Sinn. Und feels_like verwendet temperature, humidity und wind_speed – die alle im WeatherReading-Objekt stecken.

Warum diese Funktionen getrennt von den Daten halten, auf denen sie operieren? Wäre es nicht sinnvoller, sie in die Klasse zu setzen?

Probieren Sie es jetzt aus (Notebook Abschnitt 4):

  1. Definieren Sie eine WeatherReading-Klasse mit city, temperature, humidity und wind_speed
  2. Erstellen Sie drei Instanzen für drei verschiedene Städte
  3. Speichern Sie sie in einer Liste und iterieren Sie darüber:
    stations = [aalen, berlin, munich]
    for station in stations:
        print(station.city, station.temperature)
    

Methoden: Funktionen innerhalb von Klassen

Eine Methode ist einfach eine Funktion, die innerhalb einer Klasse lebt und auf den Daten dieser Klasse operiert. Anstatt Daten von außen an eine Funktion zu übergeben, hat die Methode bereits über self Zugriff auf die Daten.

Verhalten zu Daten hinzufügen

Verschieben wir unsere Umrechnungs- und Gefühlt-wie-Berechnungen in die Klasse:

class WeatherReading:
    def __init__(self, city, temperature, humidity, wind_speed):
        self.city = city
        self.temperature = temperature
        self.humidity = humidity
        self.wind_speed = wind_speed

    def to_fahrenheit(self):
        return self.temperature * 9 / 5 + 32

    def feels_like(self):
        return self.temperature - (self.wind_speed * 0.7)

Vergleichen Sie das Vorher und Nachher:

# Before (standalone function): you pass the data in
feels_like(23.5, 65.0, 12.3)

# After (method): the object already has the data
aalen = WeatherReading("Aalen", 23.5, 65.0, 12.3)
aalen.feels_like()

Die Methoden-Version ist sauberer: Das Objekt kennt seine eigenen Daten und kann Berechnungen darauf durchführen. Sie müssen sich nicht merken, welche Werte Sie übergeben müssen – sie sind bereits im Objekt enthalten.

Jetzt können Sie eine Liste von Stationen elegant verarbeiten:

stations = [
    WeatherReading("Aalen", 23.5, 65.0, 12.3),
    WeatherReading("Berlin", 19.0, 72.0, 8.5),
    WeatherReading("Munich", 21.3, 58.0, 15.1),
]

for station in stations:
    print(station.city)
    print("  Fahrenheit:", station.to_fahrenheit())
    print("  Feels like:", station.feels_like())

Die __str__-Methode: Objekte druckbar machen

Wenn Sie jetzt print(aalen) versuchen, erhalten Sie etwas Unschönes:

<__main__.WeatherReading object at 0x7f8b2c3d4e50>

Das ist Pythons Art zu sagen: “Dies ist ein WeatherReading-Objekt, gespeichert an Speicheradresse soundso.” Nicht sehr hilfreich. Sie können dies beheben, indem Sie eine spezielle Methode namens __str__ definieren:

class WeatherReading:
    def __init__(self, city, temperature, humidity, wind_speed):
        self.city = city
        self.temperature = temperature
        self.humidity = humidity
        self.wind_speed = wind_speed

    def to_fahrenheit(self):
        return self.temperature * 9 / 5 + 32

    def feels_like(self):
        return self.temperature - (self.wind_speed * 0.7)

    def __str__(self):
        return (self.city + ": " + str(self.temperature) + " C, "
                + str(self.humidity) + "% humidity, "
                + str(self.wind_speed) + " km/h wind")

Jetzt:

aalen = WeatherReading("Aalen", 23.5, 65.0, 12.3)
print(aalen)
# Aalen: 23.5 C, 65.0% humidity, 12.3 km/h wind

Methoden, deren Namen mit doppelten Unterstrichen beginnen und enden (wie __init__ und __str__), werden Dunder-Methoden genannt (kurz für “double underscore”). Sie ermöglichen es Ihnen, das Verhalten Ihrer Objekte in Python anzupassen. Sie werden im Laufe des Kurses weitere kennenlernen.

Das Problem: Eine neue Art von Station

Ihre Stadt installiert fortschrittliche Wetterstationen, die zusätzlich den UV-Index und den Luftdruck messen. Sie brauchen eine neue Klasse für diese Messungen, aber sie soll immer noch alles können, was WeatherReading bereits kann – in Fahrenheit umrechnen, die gefühlte Temperatur berechnen, schön ausgeben – plus die neuen Messwerte verarbeiten.

Kopieren Sie die gesamte WeatherReading-Klasse und fügen zwei Felder hinzu? Das würde funktionieren, aber Sie hätten zwei Kopien desselben Codes. Wenn Sie einen Fehler in einer beheben, müssen Sie daran denken, ihn auch in der anderen zu beheben.

WeatherReading
+ str city
+ float temperature
+ float humidity
+ float wind_speed
+ to_fahrenheit()
+ feels_like()
+ __str__()

Es muss einen Weg geben zu sagen: “Ich möchte eine neue Klasse, die bereits alles kann, was die alte konnte, plus mehr.”

Probieren Sie es jetzt aus (Notebook Abschnitt 5):

  1. Fügen Sie Ihrer WeatherReading-Klasse eine Methode is_comfortable(self) hinzu, die True zurückgibt, wenn die Temperatur zwischen 18 und 26 liegt und die Luftfeuchtigkeit unter 70 ist
  2. Fügen Sie eine Methode summary(self) hinzu, die einen formatierten String wie "Aalen: 23.5C, feels like 14.9C" zurückgibt
  3. Erstellen Sie drei Instanzen und rufen Sie beide Methoden auf jeder auf

Vererbung und Polymorphismus: Erweitern, was bereits funktioniert

“Ich möchte eine neue Klasse, die bereits alles kann, was die alte konnte.”

Dieser Satz ist die gesamte Motivation hinter Vererbung (Inheritance). Sie erstellen eine neue Klasse, die alle Attribute und Methoden einer bestehenden Klasse erbt, und fügen dann nur das hinzu oder ändern das, was anders ist.

Auf bestehenden Klassen aufbauen

class AdvancedReading(WeatherReading):
    def __init__(self, city, temperature, humidity, wind_speed, uv_index, pressure):
        super().__init__(city, temperature, humidity, wind_speed)
        self.uv_index = uv_index
        self.pressure = pressure

Lassen Sie uns das aufschlüsseln:

Jetzt kann die erweiterte Messung alles, was die einfache auch kann:

reading = AdvancedReading("Aalen", 23.5, 65.0, 12.3, 6.2, 1013.25)

# Inherited methods -- these just work!
print(reading.to_fahrenheit())   # 74.3
print(reading.feels_like())      # 14.89
print(reading.city)              # Aalen

# New data
print(reading.uv_index)         # 6.2
print(reading.pressure)         # 1013.25

Sie haben null Zeilen Umrechnungs- oder Gefühlt-wie-Code für AdvancedReading geschrieben. Alles wurde kostenlos von WeatherReading geerbt.

Methoden überschreiben

Was, wenn die feels_like()-Berechnung der fortschrittlichen Station auch den UV-Index berücksichtigen soll? Sie können die Methode der Elternklasse überschreiben (override), indem Sie eine neue Version in der Kindklasse definieren:

class AdvancedReading(WeatherReading):
    def __init__(self, city, temperature, humidity, wind_speed, uv_index, pressure):
        super().__init__(city, temperature, humidity, wind_speed)
        self.uv_index = uv_index
        self.pressure = pressure

    def feels_like(self):
        # Start with the basic wind chill, then add UV impact
        base = self.temperature - (self.wind_speed * 0.7)
        uv_adjustment = self.uv_index * 0.5
        return base + uv_adjustment

    def __str__(self):
        base = super().__str__()
        return base + ", UV " + str(self.uv_index) + ", " + str(self.pressure) + " hPa"

Jetzt hat AdvancedReading eine eigene feels_like()-Methode, die UV berücksichtigt, und eine eigene __str__(), die die zusätzlichen Felder einschließt. Aber to_fahrenheit() wird immer noch unverändert von WeatherReading geerbt – kein Bedarf, Funktionierendes neu zu schreiben.

Eine Schnittstelle, viele Typen

Hier wird es richtig mächtig. Sie können einfache und erweiterte Messungen in derselben Liste mischen und einheitlich behandeln:

stations = [
    WeatherReading("Aalen", 23.5, 65.0, 12.3),
    AdvancedReading("Berlin", 19.0, 72.0, 8.5, 3.1, 1015.0),
    WeatherReading("Munich", 21.3, 58.0, 15.1),
    AdvancedReading("Stuttgart", 20.7, 60.0, 10.2, 5.8, 1012.5),
]

for station in stations:
    print(station.city, "- feels like:", station.feels_like())

Python ruft automatisch die richtige Version von feels_like() auf. Für WeatherReading-Objekte verwendet es den einfachen Windchill. Für AdvancedReading-Objekte verwendet es die UV-bewusste Version. Gleicher Methodenname, unterschiedliches Verhalten je nach Objekttyp.

Dies nennt man Polymorphismus – aus dem Griechischen: “viele Formen”. Eine Schnittstelle, viele Implementierungen. Und es ist eine der mächtigsten Ideen in der Programmierung.

WeatherReading
+ str city
+ float temperature
+ float humidity
+ float wind_speed
+ to_fahrenheit()
+ feels_like()
+ __str__()
▲
inherits from
AdvancedReading
+ float uv_index
+ float pressure
+ feels_like() override
+ __str__() override

Und das ist wirklich alles, was Sie über objektorientierte Programmierung für diesen Kurs wissen müssen. Variablen, Funktionen, Klassen, Methoden, Vererbung, Polymorphismus – Sie haben die vollständige mentale Landkarte.

Probieren Sie es jetzt aus (Notebook Abschnitt 6):

  1. Erstellen Sie eine AdvancedReading-Klasse, die von WeatherReading erbt
  2. Fügen Sie uv_index- und pressure-Felder hinzu
  3. Überschreiben Sie __str__, um die neuen Felder einzuschließen
  4. Erstellen Sie eine gemischte Liste beider Typen und iterieren Sie darüber mit .feels_like()

Bibliotheken und Imports: Auf den Schultern von Riesen stehen

Sie wissen jetzt, wie Sie Ihren eigenen Code strukturieren. Aber hier ist ein Geheimnis, das jeder erfahrene Programmierer kennt: Der Großteil des Codes, den Sie brauchen, wurde bereits von jemand anderem geschrieben.

Pythons größte Stärke ist nicht nur die Sprache selbst – es ist das enorme Ökosystem von Bibliotheken (auch Pakete oder Module genannt), die Sie kostenlos verwenden können. Warum eigene Statistikfunktionen schreiben, wenn Python bereits eine mitliefert?

Eingebaute Bibliotheken

Python wird mit einer “Standardbibliothek” ausgeliefert – einer Sammlung von Modulen, die immer verfügbar sind, ohne Installation:

import statistics

daily_temps = [18.2, 21.0, 19.5, 23.5, 25.1, 22.8, 20.3]

print(statistics.mean(daily_temps))     # 21.485714285714285
print(statistics.median(daily_temps))   # 21.0
print(statistics.stdev(daily_temps))    # 2.3380903889000912

Erinnern Sie sich an die Schleife, die wir zuvor geschrieben haben, um den Durchschnitt zu berechnen? statistics.mean() tut dasselbe in einer Zeile – und behandelt Sonderfälle (wie leere Listen), die unsere Schleife nicht berücksichtigt hat.

Andere nützliche eingebaute Module:

import math
print(math.sqrt(144))       # 12.0
print(math.pi)              # 3.141592653589793

from datetime import datetime
now = datetime.now()
print(now)                   # 2026-03-11 14:30:00.123456

import random
print(random.randint(1, 6))  # a random dice roll

Die import-Anweisung lädt ein Modul. from X import Y lädt ein bestimmtes Element aus einem Modul. Das ist die gesamte Syntax, die Sie benötigen.

Bibliotheken von Drittanbietern

Jenseits der Standardbibliothek gibt es Hunderttausende von community-erstellten Paketen. Sie installieren diese mit pip (oder uv, das in diesem Kurs verwendet wird):

$ pip install numpy pandas matplotlib

Sie werden diesen im Laufe des Kurses begegnen:

Wir werden hier nicht tiefer einsteigen. Die wichtige Erkenntnis ist: Programmierung bedeutet nicht, alles von Grund auf neu zu schreiben. Es geht darum, Ihren Code mit bestehenden Werkzeugen zu kombinieren, um Probleme effizient zu lösen.

Für eine ausführliche Anleitung, wie Python-Module und Imports funktionieren, siehe Anhang 2: Python-Module.

Eigenen Code in Module organisieren

Wenn Ihre Datei zu lang wird, können Sie Ihren Code auf mehrere Dateien aufteilen. Legen Sie WeatherReading in eine eigene Datei und importieren Sie sie anderswo:

# In weather.py
class WeatherReading:
    def __init__(self, city, temperature, humidity, wind_speed):
        self.city = city
        self.temperature = temperature
        self.humidity = humidity
        self.wind_speed = wind_speed

    def to_fahrenheit(self):
        return self.temperature * 9 / 5 + 32
# In main.py
from weather import WeatherReading

aalen = WeatherReading("Aalen", 23.5, 65.0, 12.3)
print(aalen.to_fahrenheit())

Das ist dieselbe Idee wie bei der Verwendung einer fremden Bibliothek – nur dass die Bibliothek Ihr eigener Code ist. Die Denkweise ist immer dieselbe: Einmal definieren, überall wiederverwenden.

Probieren Sie es jetzt aus (Notebook Abschnitt 7):

  1. Verwenden Sie import statistics, um Mittelwert und Standardabweichung Ihrer Temperaturliste zu berechnen
  2. Verwenden Sie from datetime import datetime, um das aktuelle Datum und die Uhrzeit auszugeben
  3. Probieren Sie import this in einem Python-Terminal und lesen Sie “The Zen of Python” – es ist die Philosophie hinter Pythons Design

Das große Ganze: Wie alles zusammenhängt

Treten wir einen Schritt zurück und betrachten den Weg, den wir zurückgelegt haben. Jedes Konzept wurde eingeführt, weil das vorherige an seine Grenzen stieß:

➕
Raw calculations
variables + operators
Too much repetition
▼
𝑓
Functions
reusable blocks of logic
Too many loose parameters
▼
□
Classes
group related data
Functions separate from data
▼
▣
Methods
behavior inside classes
Want to extend without rewriting
▼
◇
Inheritance & Polymorphism
build on what exists
Don't reinvent the wheel
▼
📦
Libraries & Imports
reuse others' work
Konzept Welches Problem es löst Python-Syntax Wetter-Beispiel
Variablen & Operatoren Werte speichern und berechnen x = 23.5 Eine Temperatur umrechnen
Funktionen Wiederholung eliminieren def f(x): return ... Jede Temperatur umrechnen
Klassen Zusammengehörige Daten gruppieren class X: ... Stadt + Temp + Feuchtigkeit bündeln
Methoden Verhalten an Daten binden def f(self): ... reading.to_fahrenheit()
Vererbung Erweitern ohne Neuschreiben class Y(X): ... AdvancedReading fügt UV hinzu
Polymorphismus Eine Schnittstelle, viele Typen Gleiche Methode, anderes Verhalten Gemischte Stationsliste
Imports Bestehende Lösungen wiederverwenden import X statistics.mean(temps)

Diese Progression ist nicht willkürlich. Sie spiegelt wider, wie sich das Feld der Programmierung selbst über Jahrzehnte entwickelt hat. Frühe Programme waren nur Abfolgen von Berechnungen. Funktionen wurden erfunden, um Komplexität zu verwalten. Klassen und Objekte entstanden, als Programme groß genug wurden, dass die Gruppierung von Daten mit Verhalten unerlässlich wurde. Bibliotheken entstanden, weil niemand dasselbe Problem zweimal lösen möchte.

Sie sind gerade denselben Weg gegangen – an einem Nachmittag.


Was Sie für diesen Kurs brauchen

Atmen Sie durch. Sie haben viel Stoff behandelt, und Sie müssen nicht alles jetzt auswendig können. Dieser Anhang hat Ihnen die konzeptuelle Landkarte gegeben – das Warum hinter jeder Idee. Die Syntax wird Ihnen durch Übung zur zweiten Natur werden.

Hier ist, was für die kommenden Wochen wichtig ist:

Die wichtigste Erkenntnis zum Mitnehmen: Programmierung ist strukturiertes Problemlösen. Jedes Konzept, das Sie heute gelernt haben, existiert, weil es Ihnen hilft, Probleme effektiver zu lösen. Behalten Sie diese Denkweise bei, und die Syntax wird folgen.


Kurzreferenz: Python-Konzepte auf einen Blick

Ein kompakter Spickzettel für die in diesem Anhang behandelten Konzepte. Setzen Sie ein Lesezeichen für diese Seite und kommen Sie zurück, wann immer Sie eine Auffrischung brauchen.

Variablenzuweisung:

name = "Aalen"
temperature = 23.5

Liste:

temps = [18.2, 21.0, 19.5]

Funktion:

def celsius_to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32

Klasse mit __init__:

class WeatherReading:
    def __init__(self, city, temperature):
        self.city = city
        self.temperature = temperature

Methode:

class WeatherReading:
    def to_fahrenheit(self):
        return self.temperature * 9 / 5 + 32

Vererbung:

class AdvancedReading(WeatherReading):
    def __init__(self, city, temperature, uv_index):
        super().__init__(city, temperature)
        self.uv_index = uv_index

Import:

import statistics
from datetime import datetime
from weather import WeatherReading

Schleife:

for station in stations:
    print(station.to_fahrenheit())

Bedingung:

if temperature > 30:
    print("Hot!")
elif temperature > 20:
    print("Nice.")
else:
    print("Cool.")

Zusammenfassung und nächste Schritte

Folgendes haben Sie gelernt:

Jedes Konzept wurde durch eine reale Einschränkung des vorherigen motiviert. Das ist kein didaktischer Trick – so funktioniert Programmierung tatsächlich. Sie greifen zu neuen Werkzeugen, wenn die alten nicht mehr ausreichen.

Wie es weitergeht:

© 2026 Dominik Mueller   •  Powered by Soopr   •  Theme  Moonwalk