Anhang 0 Teil 2: Einführung in die Programmierung mit Python
March 2026 (8842 Words, 50 Minutes)
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:
- Verstehen, warum Programmierung existiert und welche Arten von Problemen sie löst
- Wissen, warum wir in diesem Kurs Python verwenden
- Einfache Berechnungen schreiben, Funktionen definieren und Klassen erstellen können
- Sehen, wie jedes Programmierkonzept natürlich aus den Grenzen des vorherigen entsteht
- Eine mentale Landkarte haben, die Sie durch den Rest dieses Kurses trägt
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:
- Wissenschaft: CERN verwendet Millionen Zeilen Code, um Teilchenkollisionen zu analysieren. Klimaforscher führen Simulationen durch, um globale Temperaturen Jahrzehnte in die Zukunft vorherzusagen. Biologen schreiben Programme, um DNA-Sequenzen verschiedener Arten zu vergleichen.
- Ingenieurwesen: Die Mars-Rover der NASA werden durch Software gesteuert, die auf der Erde geschrieben wurde. Automobilingenieure simulieren Crashtests, bevor ein einziges Stück Metall gebogen wird. Architekten nutzen rechnergestützte Werkzeuge zur Optimierung von Gebäudestrukturen.
- Medizin: Machine-Learning-Modelle erkennen Tumore in Röntgenbildern. Epidemiologen modellieren die Ausbreitung von Krankheiten. Pharmakologen simulieren, wie Wirkstoffmoleküle mit Proteinen interagieren.
- Finanzwesen: Banken verarbeiten Millionen Transaktionen pro Sekunde. Algorithmische Handelssysteme treffen Entscheidungen in Mikrosekunden. Risikomodelle sagen Marktverhalten vorher.
- Kunst und Medien: Pixar rendert ganze Filme mit maßgeschneiderter Software. Musiker erzeugen Klänge mit Code. Spieleentwickler erschaffen virtuelle Welten.
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:
- Was, wenn Sie 100 Städte statt 5 hätten?
- Was, wenn sich die Umrechnungsformel ändern müsste (vielleicht möchten Sie auf eine Dezimalstelle runden)?
- Was, wenn Sie einen Tippfehler in einer Zeile gemacht haben, aber nicht in den anderen?
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:
- Erstellen Sie eine Variable
celsiusmit der heutigen ungefähren Temperatur- Rechnen Sie sie mit der Formel in Fahrenheit um:
fahrenheit = celsius * 9 / 5 + 32- 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.
Probieren Sie es jetzt aus (Notebook Abschnitt 3):
- Schreiben Sie eine Funktion
celsius_to_fahrenheit(celsius), die Celsius in Fahrenheit umrechnet- Schreiben Sie eine Funktion
feels_like(temp, humidity, wind), dietemp - (wind * 0.7)zurückgibt- Rufen Sie beide Funktionen für drei verschiedene Städte auf
- Beachten Sie, wie viele Argumente Sie jedes Mal wiederholen
Klassen: Zusammengehörige Daten gruppieren
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:
class WeatherReading:– wir definieren einen neuen Objekttyp namensWeatherReadingdef __init__(self, ...):– diese spezielle Funktion wird ausgeführt, wenn Sie eine neue Instanz erstellen. Stellen Sie es sich als “Formular ausfüllen” vorselfbezieht sich auf die Instanz, die gerade erstellt wird – das spezifische Formular, das Sie gerade ausfüllenself.temperature = temperaturespeichert den Wert innerhalb der Instanz
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):
- Definieren Sie eine
WeatherReading-Klasse mitcity,temperature,humidityundwind_speed- Erstellen Sie drei Instanzen für drei verschiedene Städte
- 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.
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):
- Fügen Sie Ihrer
WeatherReading-Klasse eine Methodeis_comfortable(self)hinzu, dieTruezurückgibt, wenn die Temperatur zwischen 18 und 26 liegt und die Luftfeuchtigkeit unter 70 ist- Fügen Sie eine Methode
summary(self)hinzu, die einen formatierten String wie"Aalen: 23.5C, feels like 14.9C"zurückgibt- 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:
class AdvancedReading(WeatherReading):– die Klammern bedeuten “diese Klasse erbt vonWeatherReading.”AdvancedReadingist die Kindklasse,WeatherReadingist die Elternklasse.super().__init__(...)– ruft das__init__der Elternklasse auf, um die Felder einzurichten, dieWeatherReadingbereits verwaltet. Kein Bedarf,self.city = cityund so weiter zu wiederholen.- Wir fügen nur das hinzu, was neu ist:
uv_indexundpressure.
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.
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):
- Erstellen Sie eine
AdvancedReading-Klasse, die vonWeatherReadingerbt- Fügen Sie
uv_index- undpressure-Felder hinzu- Überschreiben Sie
__str__, um die neuen Felder einzuschließen- 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:
- NumPy – schnelles numerisches Rechnen mit Arrays
- Pandas – Datenanalyse und -verarbeitung
- Matplotlib – Erstellung von Diagrammen und Grafiken
- Pytest – Testen Ihres Codes (das werden Sie häufig verwenden)
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):
- Verwenden Sie
import statistics, um Mittelwert und Standardabweichung Ihrer Temperaturliste zu berechnen- Verwenden Sie
from datetime import datetime, um das aktuelle Datum und die Uhrzeit auszugeben- Probieren Sie
import thisin 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ß:
| 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:
- Vorlesung 1 wird Sie durch die Einrichtung von Python, Git und VS Code führen. Sie werden vom ersten Tag an echten Code schreiben und ausführen.
- Anhang 2 geht tiefer auf Imports, Module und Pakete ein, wenn Sie bereit sind.
- Jede Vorlesung wird auf den Konzepten aus diesem Anhang aufbauen. Wenn Sie im Kursmaterial auf eine Klasse oder eine Funktion stoßen, werden Sie wissen, warum sie existiert – nicht nur wie man sie schreibt.
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:
- Programmierung existiert, um Probleme zu lösen – von kleinen Berechnungen bis zu Anwendungen globalen Ausmaßes
- Python lässt Sie ohne Kompilierungsschritt von der Idee zum funktionierenden Code gelangen
- Variablen und Operatoren ermöglichen es Ihnen, Daten zu speichern und Ergebnisse zu berechnen
- Funktionen eliminieren Wiederholung durch Kapselung wiederverwendbarer Logik
- Klassen gruppieren zusammengehörige Daten zu kohärenten Objekten
- Methoden binden Verhalten direkt an Daten
- Vererbung und Polymorphismus ermöglichen Erweiterung und Spezialisierung ohne Neuschreiben
- Bibliotheken lassen Sie auf der Arbeit der globalen Programmiergemeinschaft aufbauen
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:
- Anhang 0 Teil 1: Terminal- und CLI-Grundlagen – falls Sie ihn noch nicht gelesen haben
- Vorlesung 1: Moderne Entwicklungswerkzeuge – praktische Einrichtung von Python, Git und VS Code
- Einführung in modernes Software Engineering – der Gesamtüberblick über den Kurs
- Anhang 2: Python-Module – vertiefte Behandlung von Imports und Paketen