Funktionen programmieren: Aufbau und Anwendung
Eine Funktion bündelt eine klar umrissene Aufgabe unter einem Namen. Du kannst ihr Werte übergeben und ihr Ergebnis an anderer Stelle weiterverwenden. So zerlegst du größere Probleme in überschaubare, wiederverwendbare Teile.
Auf dieser Seite planst du Funktionsschnittstellen, setzt sie in Python um und prüfst, ob Ein- und Ausgaben zusammenpassen.
Hake ab, was du schon kannst — und komm am Ende hierher zurück!
Was macht eine Funktion aus?
Stell dir vor, dein Programm muss an mehreren Stellen einen Gesamtpreis berechnen. Statt die Rechnung jedes Mal neu zu schreiben, legst du sie einmal als Funktion fest.
Funktion
Eine Funktion ist ein benannter, wiederverwendbarer Programmteil. Parameter sind Platzhalter für Eingaben. Beim Aufruf eingesetzte Werte heißen Argumente. Mit return kann die Funktion einen Wert an die aufrufende Stelle zurückgeben.
In Python sieht eine einfache Definition zeilenweise so aus:
def berechne_gesamtpreis(menge, einzelpreis):return menge * einzelpreis
Die erste Zeile bildet den Funktionskopf. Er enthält das Schlüsselwort def, den Namen und die Parameter. Der eingerückte Funktionsrumpf beschreibt die Berechnung.
Die Definition führt die Rechnung noch nicht aus. Erst berechne_gesamtpreis(4, 12) ist ein Aufruf. Dabei erhält menge den Wert 4 und einzelpreis den Wert 12. Die Funktion gibt 48 zurück.
Die Definition legt fest, was geschehen soll. Der Aufruf führt die Funktion mit konkreten Argumenten aus.
Wie planst du eine klare Schnittstelle?
Bevor du programmierst, solltest du die Schnittstelle der Funktion festlegen. Sie beschreibt, wie anderer Programmcode die Funktion benutzt.
Funktionsschnittstelle
Zu einer klaren Funktionsschnittstelle gehören:
- ein Name, der die Aufgabe beschreibt;
- die benötigten Parameter;
- der zurückgegebene Wert;
- eine Vorbedingung, falls nicht jede Eingabe erlaubt oder sinnvoll ist.
Für die Gesamtpreisfunktion passt folgende Planung:
| Bestandteil | Festlegung |
|---|---|
| Name | berechne_gesamtpreis |
| Parameter | menge, einzelpreis |
| Rückgabewert | Gesamtpreis |
| Vorbedingung | Menge und Einzelpreis sind nicht negativ. |
Eine Vorbedingung sagt, was vor dem Aufruf gelten muss. Sie verhindert Missverständnisse über den erlaubten Eingabebereich. In umfangreicheren Programmen kann eine Funktion solche Bedingungen zusätzlich prüfen.
Der Rückgabewert lässt sich direkt speichern oder weiterverarbeiten:
preis = berechne_gesamtpreis(4, 12)endpreis = preis - 12
Nach dem ersten Schritt enthält preis den Wert 48; nach dem zweiten enthält endpreis den Wert 36.
Wie zerlegst du ein größeres Problem?
Angenommen, ein Programm soll den Endpreis einer Ticketbestellung mit Rabatt berechnen. Die Gesamtaufgabe lässt sich in drei Teilprobleme zerlegen:
- Gesamtpreis vor dem Rabatt berechnen.
- Rabattbetrag berechnen.
- Rabattbetrag vom Gesamtpreis abziehen.
Jedes Teilproblem erhält eine eigene Funktion:
berechne_gesamtpreis(menge, einzelpreis)liefertmenge * einzelpreis.berechne_rabatt(summe, prozent)liefertsumme * prozent / 100.berechne_endpreis(summe, rabatt)liefertsumme - rabatt.
Vier Tickets kosten jeweils 12 Euro. Der Rabatt beträgt 25 Prozent.
berechne_gesamtpreis(4, 12)ergibt 48 Euro.berechne_rabatt(48, 25)ergibt 12 Euro.berechne_endpreis(48, 12)ergibt 36 Euro.
Der entscheidende Gedanke ist die Verbindung der Ausgaben und Eingaben: Der Rückgabewert einer Funktion wird zum Argument der nächsten Funktion.
Die Gesamtpreisfunktion ist nicht auf diesen einen Fall festgelegt. berechne_gesamtpreis(3, 12) liefert 36 Euro, während berechne_gesamtpreis(2, 15) 30 Euro liefert. Derselbe Programmteil arbeitet in unterschiedlichen Aufrufkontexten, weil die veränderlichen Werte als Argumente übergeben werden.
Eine sinnvolle Zerlegung gibt jedem Teilproblem eine klare Aufgabe und verbindet die Funktionen über ausdrücklich benannte Ein- und Ausgaben.
Rückgabe, Ausgabe und Nebeneffekt unterscheiden
return und print erfüllen verschiedene Aufgaben:
returngibt einen Wert an den aufrufenden Programmteil zurück.printerzeugt eine sichtbare Ausgabe, liefert aber nicht automatisch den angezeigten Wert zur Weiterverarbeitung.
Eine Python-Funktion ohne ausdrückliches return gibt den besonderen Wert None zurück. Wenn du eine Zahl erwartest und stattdessen None erhältst, hast du möglicherweise return vergessen.
Diese Funktion zeigt nur Text an:
def zeige_preis(preis):print(preis)
Diese Funktion liefert dagegen einen berechneten Wert:
def verdopple(wert):return 2 * wert
Das Ergebnis von verdopple(15) ist 30 und kann gespeichert oder als Argument weitergereicht werden.
In manchen Sprachen bezeichnet man ein Unterprogramm ohne Rückgabewert als Prozedur. Die Bezeichnungen unterscheiden sich jedoch zwischen Programmiersprachen. Python nennt auch Definitionen ohne ausdrückliches return Funktionen.
Eine Veränderung, die außerhalb der Funktion beobachtbar ist, heißt Nebeneffekt. Beispiele sind eine Ausgabe oder die Veränderung einer globalen Variablen. Globale Variablen sind außerhalb der Funktion definiert und können dadurch versteckte Abhängigkeiten schaffen.
Reine Funktion
Eine reine Funktion liefert für dieselben Eingaben stets dasselbe beobachtbare Ergebnis und verursacht keine von außen beobachtbaren Zustandsänderungen. Ihr Aufruf kann deshalb gedanklich durch seinen Rückgabewert ersetzt werden.
Nicht jede Funktion in jedem Programm muss rein sein. Klare Parameter und Rückgabewerte machen Abhängigkeiten aber sichtbar und erleichtern das Nachvollziehen und Testen.
Wie werden Funktionen selbst zu Werten?
In Python und in funktionalem Programmierstil können Funktionen ähnlich wie andere Werte gespeichert oder übergeben werden.
Bei operation = verdopple fehlen die Aufrufklammern absichtlich. Die Variable operation verweist dadurch auf die Funktion selbst. operation = verdopple(15) würde dagegen sofort den Rückgabewert 30 speichern.
Eine Funktion kann auch eine andere Funktion als Parameter erhalten:
def wende_an(funktion, wert):return funktion(wert)
Der Aufruf wende_an(verdopple, 15) übergibt verdopple ohne Aufrufklammern. Erst innerhalb von wende_an wird sie mit dem Wert 15 aufgerufen. Das Ergebnis ist 30.
Funktion höherer Ordnung
Eine Funktion höherer Ordnung erhält mindestens eine Funktion als Argument oder gibt eine Funktion zurück. Dadurch kann ein allgemeiner Ablauf mit unterschiedlichem Verhalten kombiniert werden.
Auch map folgt dieser Idee: Die übergebene Funktion wird auf jedes Element einer Liste angewendet. Das Verfahren bleibt gleich, während die konkrete Funktion wechseln kann.
Eine Funktion systematisch entwerfen
Nutze beim Entwerfen diese Reihenfolge:
- Formuliere das Teilproblem in einem Satz.
- Wähle einen Namen, der dieses Teilproblem beschreibt.
- Bestimme alle nötigen Eingaben als Parameter.
- Lege Rückgabewert und mögliche Vorbedingungen fest.
- Implementiere nur die geplante Aufgabe.
- Rufe die Funktion mit mindestens zwei passenden Eingabesätzen auf.
- Prüfe Rückgabewert, Einheit und Bedeutung im Sachzusammenhang.
Aufgabe: Entwirf eine Funktion, die einen Preis nach Abzug eines Rabattbetrags liefert. Verwende sie einmal für 48 Euro mit 12 Euro Rabatt und einmal für 36 Euro mit 6 Euro Rabatt.
Lösung:
- Teilproblem: Ziehe den Rabattbetrag vom bisherigen Preis ab.
- Name:
berechne_endpreis - Parameter:
summe,rabatt - Rückgabewert: Preis nach dem Abzug
- Vorbedingung: Beide Beträge sind nicht negativ; der Rabatt ist nicht größer als die Summe.
Implementierung:
def berechne_endpreis(summe, rabatt):return summe - rabatt
Die Aufrufe liefern berechne_endpreis(48, 12) = 36 und berechne_endpreis(36, 6) = 30.
Prüfe nicht nur, ob der Code ausgeführt wird. Frage auch, ob der Rückgabewert im jeweiligen Zusammenhang sinnvoll ist. Ein negativer Endpreis würde beispielsweise die festgelegte Vorbedingung verletzen.
Karteikasten
Überlege zuerst selbst und drehe die Karte anschließend zum Prüfen um.
Alles auf einen Blick
- Funktionen programmieren
- Aufbau: Kopf, Parameter und eingerückter Rumpf
- Verwendung: Definition festlegen und anschließend aufrufen
- Schnittstelle: Name, Eingaben, Rückgabewert und Vorbedingung
- Zerlegung: Gesamtproblem in verbundene Teilprobleme aufteilen
- Rückgabe: Ergebnisse mit `return` weiterverwendbar machen
- Nachvollziehbarkeit: versteckte globale Abhängigkeiten vermeiden
- Erweiterung: Funktionen als Werte übergeben
Abschluss-Check
Du kannst eine Funktion sicher einsetzen, wenn du ihre Aufgabe, Eingaben, Bedingungen und Rückgabe klar benennen kannst. Bei größeren Problemen wiederholst du diesen Entwurf für jedes Teilproblem und verbindest die Funktionen über ihre sichtbaren Schnittstellen.
Mit Google fortfahren