Lernziele dieses Kapitels
- Du definierst Funktionen mit def und verstehst return
- Du nutzt Parameter, Default-Werte und Typ-Hinweise
- Du verwendest *args und **kwargs für flexible Argumente
- Du baust PyBuddy's Hilfsfunktionen
Funktionen definieren
Mit def kapselst du Code in wiederverwendbare Bausteine. Eine Funktion ist wie ein Rezept: Du gibst Zutaten (Parameter) hinein und bekommst ein Ergebnis (return) zurück.
Pro Tipp
Gute Funktionen machen eine Sache und machen sie gut. Wenn deine Funktion mehr als 20 Zeilen hat, überlege, ob du sie aufteilen kannst.
# Einfache Funktion
def begruesse(name):
"""Gibt eine Begrüßung zurück."""
return f"Hallo {name}! Willkommen bei PyBuddy."
# Aufruf
text = begruesse("Max")
print(text)
# Mehrere Parameter
def addiere(a, b):
return a + b
print(addiere(5, 3)) # 8
print(addiere(10, 20)) # 30
Du kennst bereits JavaScript aus dem JS-Quest. Hier ist der direkte Vergleich:
def begruesse(name):
return f"Hallo {name}!"
function begruesse(name) {
return `Hallo ${name}!`;
}
def name(): und Einrückung. JavaScript: function name() {} und geschweifte Klammern. Die Logik ist identisch!Parameter und Default-Werte
Funktionen können optionale Parameter mit Default-Werten haben. Du kannst auch benannte Argumente übergeben — dann ist die Reihenfolge egal.
# Default-Werte
def erstelle_charakter(name, klasse="Krieger", level=1):
return {"name": name, "klasse": klasse, "level": level}
# Verschiedene Aufrufe
c1 = erstelle_charakter("Max")
c2 = erstelle_charakter("Anna", "Magier")
c3 = erstelle_charakter("Ben", level=5, klasse="Schurke")
print(c1)
print(c2)
print(c3)
# Typ-Hinweise (Python 3.5+)
def quadriere(zahl: int) -> int:
return zahl ** 2
print(quadriere(4)) # 16
Du kennst bereits JavaScript aus dem JS-Quest. Hier ist der direkte Vergleich:
def erstelle(name, klasse="Krieger", level=1):
return {...}
function erstelle(name, klasse = 'Krieger', level = 1) {
return { name, klasse, level };
}
*args und **kwargs
Manchmal weißt du nicht im Voraus, wie viele Argumente eine Funktion bekommt. *args sammelt beliebig viele positionale Argumente als Tuple, **kwargs sammelt benannte Argumente als Dictionary.
# *args — beliebig viele Zahlen
def summe(*zahlen):
ergebnis = 0
for z in zahlen:
ergebnis += z
return ergebnis
print(summe(1, 2, 3)) # 6
print(summe(10, 20)) # 30
# **kwargs — beliebig viele benannte Werte
def zeige_profile(**daten):
for key, value in daten.items():
print(f"{key}: {value}")
zeige_profile(name="Max", alter=17, ort="Wien")
# Kombiniert
def universal(a, b, *args, **kwargs):
print(f"a={a}, b={b}, args={args}, kwargs={kwargs}")
universal(1, 2, 3, 4, modus="test", aktiv=True)
Du kennst bereits JavaScript aus dem JS-Quest. Hier ist der direkte Vergleich:
def summe(*zahlen):
return sum(zahlen)
def zeige(**kwargs):
print(kwargs)
function summe(...zahlen) {
return zahlen.reduce((a, b) => a + b, 0);
}
function zeige(kwargs) {
console.log(kwargs);
}
*args und **kwargs. JavaScript: ...args (Rest-Parameter) für Positionale, aber kein direktes **kwargs — da nutzt man Objekte.Lambda-Funktionen
Lambda-Funktionen sind kleine, anonyme Funktionen in einer Zeile. Sie sind perfekt für kurze Operationen, die du nicht extra mit def definieren willst.
# Lambda-Syntax
quadrat = lambda x: x ** 2
print(quadrat(5)) # 25
# Mit mehreren Parametern
addiere = lambda a, b: a + b
print(addiere(3, 7)) # 10
# Direkt nutzen (z.B. als Sortierschlüssel)
spieler = [
{"name": "Anna", "punkte": 120},
{"name": "Ben", "punkte": 95},
{"name": "Clara", "punkte": 150}
]
spieler.sort(key=lambda s: s["punkte"], reverse=True)
for s in spieler:
print(f"{s['name']}: {s['punkte']}")
Du kennst bereits JavaScript aus dem JS-Quest. Hier ist der direkte Vergleich:
quadrat = lambda x: x ** 2
spieler.sort(key=lambda s: s['punkte'])
let quadrat = x => x ** 2;
spieler.sort((a, b) => b.punkte - a.punkte);
lambda x: x**2. JavaScript: x => x**2 (Arrow Function). Beides sind anonyme Einzeiler, aber JS Lambdas sind flexibler.Scope und Docstrings
Variablen innerhalb einer Funktion sind lokal — sie existieren nur dort. Variablen außerhalb sind global. Docstrings (drei Anführungszeichen direkt unter def) dokumentieren deine Funktion.
# Scope
level = 10 # Global
def level_up():
level = 20 # Lokal!
print(f"Innerhalb: {level}")
level_up()
print(f"Außerhalb: {level}") # Bleibt 10!
# Docstring
def berechne_schaden(waffe, staerke):
"""Berechnet den Schaden basierend auf Waffe und Stärke.
Args:
waffe: Name der Waffe
staerke: Stärkewert (1-100)
Returns:
Berechneter Schaden als int
"""
return int(staerke * 1.5 + 10)
print(berechne_schaden("Schwert", 40)) # 70
print(berechne_schaden.__doc__) # Zeigt die Docstring
Warm-Up: Temperatur-Umrechner
Schreibe zwei Funktionen: c_to_f(c) und c_to_k(c). Rufe sie mit einer Benutzer-Eingabe auf.
Hinweis: def c_to_f(c):
return c * 9/5 + 32
def c_to_k(c):
return c + 273.15
c = float(input("Celsius: "))
print(f"{c}°C = {c_to_f(c):.1f}°F")
print(f"{c}°C = {c_to_k(c):.2f}K")
def c_to_f(c):
return c * 9/5 + 32
def c_to_k(c):
return c + 273.15
c = float(input("Celsius: "))
print(f"{c}°C = {c_to_f(c):.1f}°F")
print(f"{c}°C = {c_to_k(c):.2f}K")
Challenge: Login-Validator
Erstelle eine Funktion ist_gueltig(benutzer, passwort), die prüft: Benutzer mindestens 3 Zeichen, Passwort mindestens 8 Zeichen. Gib True oder False zurück.
Hinweis: def ist_gueltig(benutzer, passwort):
if len(benutzer) < 3:
return False
if len(passwort) < 8:
return False
return True
user = input("Benutzer: ")
pw = input("Passwort: ")
if ist_gueltig(user, pw):
print(" Gültig!")
else:
print(" Ungültig!")
def ist_gueltig(benutzer, passwort):
if len(benutzer) < 3:
return False
if len(passwort) < 8:
return False
return True
user = input("Benutzer: ")
pw = input("Passwort: ")
if ist_gueltig(user, pw):
print(" Gültig!")
else:
print(" Ungültig!")
PyBuddy-Checkpoint: Formatierungs-Helfer
PyBuddy bekommt Hilfsfunktionen für Text-Formatierung und Validierung, die später im gesamten Projekt genutzt werden.
Hinweis: # pybuddy/main.py
def formatiere_text(text):
"""Entfernt Leerzeichen und macht ersten Buchstaben groß."""
return text.strip().title()
def ist_leer(eingabe):
"""Prüft ob Eingabe leer ist."""
return len(eingabe.strip()) == 0
# Test
name = formatiere_text(" max mustermann ")
print(name) # Max Mustermann
print(ist_leer(" ")) # True
# pybuddy/main.py
def formatiere_text(text):
"""Entfernt Leerzeichen und macht ersten Buchstaben groß."""
return text.strip().title()
def ist_leer(eingabe):
"""Prüft ob Eingabe leer ist."""
return len(eingabe.strip()) == 0
# Test
name = formatiere_text(" max mustermann ")
print(name) # Max Mustermann
print(ist_leer(" ")) # True
In Super Mario Bros. gibt es eine Funktion springen(), die prüft: Steht Mario auf dem Boden? Dann setze Geschwindigkeit Y auf -15. Jeder Sprung im Spiel ist ein Funktionsaufruf mit Parametern — genau wie du es jetzt programmierst!
Zusammenfassung
- def name(): → Funktion definieren
- Parameter + Default-Werte für Flexibilität
- *args, **kwargs für beliebige Argumente
- Lambda für kurze anonyme Funktionen
- Docstrings dokumentieren deinen Code