Python-Kurs / Funktionen definieren und Werte mit return zurückgeben

Eine Funktion bündelt eine benannte Verarbeitung: Sie erhält Eingaben über Parameter und gibt mit return ein Ergebnis zurück. Eine Zahl zurückzugeben ist etwas anderes, als sie mit print anzuzeigen; getrennte Berechnung und Ausgabe machen dieselbe Logik für weitere Rechnungen und Tests nutzbar.

Definition, Parameter und Aufruf unterscheiden

Die Anweisung def legt den Funktionsnamen und die Parameter fest; der eingerückte Block ist der Funktionskörper. Ein Parameter ist ein Name in der Definition, beispielsweise amount. Ein Argument ist der tatsächlich übergebene Wert, beispielsweise 8000. Bei jedem Aufruf werden die Argumente an die passenden Parameter gebunden und der Körper ausgeführt.

Die Ausführung der Definition legt die Funktion an, führt aber den Körper noch nicht aus. Erst der Aufruf mit Klammern startet die Verarbeitung. return beendet diesen Aufruf und übergibt den angegebenen Wert an den Aufrufer. Ein leeres return oder das Erreichen des Funktionsendes ohne Rückgabe liefert None. Das ist ein eigener Wert, keine Null und kein leerer Text.

Im Beispiel wird eine Summe zurückgegeben und erst außerhalb angezeigt. So kann die aufrufende Stelle selbst entscheiden, ob sie das Ergebnis addiert, prüft oder ausgibt. Die Python-Einführung zu Funktionsdefinitionen erklärt Parameter und Aufrufe.

Ergebnisse einer Berechnungsfunktion wiederverwenden

Speichern Sie den folgenden vollständigen Code als functions.py in UTF-8 im Übungsordner. Führen Sie python functions.py mit dem ausgewählten Projektinterpreter aus. Ohne aktivierte Umgebung kann unter macOS oder Ubuntu python3 der richtige Befehlsname sein. Das Beispiel benötigt weder Zusatzpakete noch Eingabedateien.

def total_with_fee(amount, fee):
    """Return the sum of the amount and fee."""
    return amount + fee

first = total_with_fee(8000, 500)
second = total_with_fee(3500, 0)
print(first, second)
print(first + second)

Erwartete Ausgabe:

8500 3500
12000

Der erste Aufruf bindet 8000 an amount und 500 an fee; sein Ergebnis 8500 wird in first gespeichert. Der zweite Aufruf arbeitet mit 3500 und 0 und liefert 3500. Die erste Ausgabe zeigt die beiden gespeicherten Zahlen, die zweite ihre Summe 12000. Die Berechnungsfunktion selbst schreibt nichts auf den Bildschirm.

Die englische Zeichenkette direkt am Anfang des Körpers ist die Dokumentationszeichenkette, auch Docstring genannt. Sie erklärt den Zweck und ist über total_with_fee.__doc__ lesbar. Ihr Text wird hier weder als Eingabeaufforderung noch als Berechnung ausgeführt.

Eine klare Aufgabe und passende Eingaben festlegen

Der Name total_with_fee benennt die Addition eines Betrags und einer Gebühr. Die Funktion fragt keine Daten ab und speichert keine Datei. Diese kleine Verantwortung lässt sich unabhängig prüfen: Für dieselben numerischen Argumente erwarten Sie dieselbe Summe. Zusätzliche Darstellung oder Datenspeicherung kann die aufrufende Stelle übernehmen.

Der gezeigte Code prüft weder Zahlenarten noch Geschäftsregeln. Negative Beträge werden addiert, Dezimalwerte werden ebenfalls akzeptiert. Zwei Zeichenketten würden mit + aneinandergehängt, eine Zahl und eine Zeichenkette dagegen einen TypeError auslösen. Beschreiben Sie daher die Annahme „zwei addierbare Zahlen“ und entscheiden Sie beim Einlesen oder an einer geeigneten Schnittstelle, welche Eingaben erlaubt sind. Ein Funktionsname oder Docstring erzwingt diese Regel nicht.

Operation im Körper Ergebnis beim Aufrufer Sichtbare Ausgabe
return amount + fee Berechnete Summe Keine durch diese Anweisung
print(amount + fee) ohne nachfolgende Rückgabe None Summe wird angezeigt
return ohne Wert None Keine durch diese Anweisung

Auch print selbst liefert None. Die Variante return print(amount + fee) würde deshalb trotz des Wortes return nicht die Summe zurückgeben. Die Sprachreferenz zu return und die Referenz zu print beschreiben die beiden Aufgaben.

Fehlende Ergebnisse und fehlerhafte Aufrufe untersuchen

  1. Ändern Sie nur die erste Gebühr von 500 in 1000. Erwarten Sie 9000 3500 und anschließend 12500. Stellen Sie die Gebühr danach wieder auf 500.
  2. Ersetzen Sie versuchsweise die Rückgabezeile durch print(amount + fee). Beide Aufrufe zeigen dann ihre Zahlen bereits während der Verarbeitung; print(first, second) zeigt None None. Die anschließende Addition der beiden Rückgabewerte scheitert mit TypeError. Stellen Sie return amount + fee wieder her.
  3. Rufen Sie in einem frisch gestarteten Skript total_with_fee(8000, 500) vor der Definition auf. Ein NameError entsteht, weil der Name zu diesem Zeitpunkt noch nicht gebunden ist. Verschieben Sie den Aufruf wieder unter die Definition. Eine interaktive Sitzung, in der die Funktion bereits existiert, wäre hierfür kein gleichwertiger frischer Test.
  4. Lassen Sie bei einem Aufruf die Gebühr weg. Der Aufruf erhält einen TypeError, da beide Parameter in dieser Definition erforderlich sind. Vergleichen Sie die Parameterliste mit der Anzahl und Benennung der übergebenen Argumente.

amount und fee sind lokale Namen des jeweiligen Aufrufs und normalerweise außerhalb nicht direkt lesbar. Geben Sie benötigte Ergebnisse ausdrücklich zurück, statt auf versteckte externe Änderungen zu setzen. Wenn ein Aufruf unerwartet None liefert, verfolgen Sie insbesondere jeden möglichen Pfad bis zu einem return oder zum Funktionsende und kontrollieren Sie danach erneut die beiden ursprünglichen Ausgabezeilen.