Zum Inhalt
wannacode

Parameter und return

Kurz gesagt: Ein Parameter ist eine Variable der Funktion, die den Wert aus dem Aufruf (das Argument) bekommt, und return gibt ein Ergebnis an den Aufrufer zurück.

Problem

Ein Bon, verschiedene Summen

Du willst eine Funktion, die die letzte Zeile des Bons ausgibt: „Summe: … €“. Aber die Summe ist bei jeder Bestellung anders.

Die Funktionen aus der letzten Lektion geben immer dasselbe aus. Eine Funktion print_total() kann die Summe nicht kennen. Eine eigene Funktion für jede Summe willst du auch nicht. Du brauchst einen Weg, der Funktion die Summe beim Aufruf zu übergeben.

Die Idee

Parameter: was die Funktion bekommt

In die Klammern schreibst du einen Namen für das, was die Funktion erwartet. Das ist ein Parameter. In der Funktion ist er eine ganz normale Variable.

Beim Aufruf schreibst du den Wert in die Klammern. Dieser Wert heißt Argument.

def print_total(total):
print(f"Summe: {total} €")
print_total(12.5)
print_total(4.2)
Ausgabe
Summe: 12.5 €
Summe: 4.2 €

total ist der Parameter. 12.5 und 4.2 sind die Argumente. Es gibt eine Funktion, und sie gibt verschiedene Summen aus.

Vor den Parameter schreibst du keinen Typ: Python prüft nicht, was du übergibst. Übergibst du Text statt einer Zahl, gibt die Funktion ihn aus, ohne sich zu beschweren. Deshalb muss der Name des Parameters klar sagen, was erwartet wird.

Gibt es mehrere Parameter, trennst du sie mit Kommas. Die Argumente werden in derselben Reihenfolge übergeben.

Probier es aus

Nach Position, nicht nach Name

Was gibt das Programm aus?

def print_line(item, qty):
print(f"{item}: {qty} Stk.")
coffee = "Kaffee"
qty = 3
print_line(coffee, 2)
Antwort

Problem

Warum ist der Preis nicht gesunken?

Du hast eine Funktion für 10 % Rabatt geschrieben und sie aufgerufen:

def apply_discount(price):
price = price * 0.9
price = 100
apply_discount(price)
print(price) # 100
Ausgabe
100

Der Preis ist immer noch 100. Die Funktion meldet keinen Fehler, und trotzdem ist der Rabatt nicht da. Wo ist er geblieben?

Sieh es dir an

Die Funktion bekommt den Wert

def apply_discount(price):
price = price * 0.9
price = 100
apply_discount(price)
print(price) # 100
Schritt für Schritt, in Worten
  1. Im Programm gibt es eine Variable price = 100.
  2. Du rufst apply_discount(price) auf: Für die Funktion wird neuer Speicher bereitgestellt.
  3. Ihr Parameter price bekommt den Wert 100.
  4. Die Funktion rechnet 100 * 0.9 = 90 aus und speichert die neue Zahl in ihrem eigenen price.
  5. Die Funktion endet, und ihr Speicher verschwindet, zusammen mit ihrem price.
  6. Und price im Programm ist immer noch 100.

Beim Aufruf bekommt die Funktion nicht die Variable price selbst, sondern ihren Wert, in ihrer eigenen Variable price. Die Zeile price = price * 0.9 legt die neue Zahl 90 in die Variable der Funktion. Wenn die Funktion endet, verschwindet ihr Speicher und mit ihm diese 90. Draußen hat sich nichts geändert: Es ist, als hätte die Funktion eine Kopie bekommen. Das nennt man Wertübergabe (pass by value).

Die beiden Variablen heißen absichtlich gleich (price): Genau das verwirrt in der Praxis. Der Name spielt keine Rolle. Jede Funktion hat ihre eigenen Variablen.

Genauer, für Neugierige

Genau genommen kopiert Python die Zahl nicht. Der Parameter zeigt auf dieselbe Zahl 100, auf die auch price draußen zeigt. Aber eine Zahl lässt sich nicht an Ort und Stelle ändern: price = … lässt nur den Namen der Funktion auf eine andere Zahl zeigen, und price draußen zeigt weiter auf 100. Deshalb ist das Ergebnis bei Zahlen und Text dasselbe wie mit einer Kopie. Bei Listen ist es anders: Die Funktion kann die Liste selbst ändern (zum Beispiel mit append), und die Änderung ist auch draußen zu sehen:

def add_item(items):
items.append("Milch")
cart = ["Brot"]
add_item(cart)
print(cart)
Ausgabe
['Brot', 'Milch']

Die Idee

return: Die Funktion gibt ein Ergebnis zurück

Die Lösung: Die Funktion gibt den neuen Preis zurück. In den Rumpf schreibst du return und den Wert. Einen Typ für das Ergebnis schreibst du nicht: def bleibt gleich, ob die Funktion etwas zurückgibt oder nicht.

def apply_discount(price):
return price * 0.9
price = 100
price = apply_discount(price)
print(price) # 90.0
Schritt für Schritt, in Worten
  1. Im Programm: price = 100.
  2. Du rufst apply_discount(price) auf: Für die Funktion wird Speicher bereitgestellt.
  3. Der Parameter price bekommt den Wert 100.
  4. return price * 0.9: Das Ergebnis ist 90.
  5. Das Ergebnis geht zurück ans Programm und wird in price gespeichert.
  6. Jetzt ist price im Programm 90.

Der Aufruf apply_discount(price) ist jetzt ein Wert. Du kannst ihn in einer Variable speichern (wie hier), ausgeben oder mit ihm rechnen.

Genauer, für Neugierige
  • Eine Funktion ohne return gibt trotzdem etwas zurück: None, den Wert für „nichts“. Gibst du das Ergebnis der ersten Version aus, die nur ihre eigene Kopie gesenkt hat, siehst du genau das:
def apply_discount(price):
price = price * 0.9
print(apply_discount(100))
Ausgabe
None
  • Du kannst return auch ohne Wert schreiben. Es beendet einfach die Funktion.
  • Eine Funktion kann mehrere Werte auf einmal zurückgeben: Du zählst sie nach return mit Kommas auf und speicherst sie beim Aufruf in ebenso vielen Variablen:
def get_limits():
return 1, 10
low, high = get_limits()
print(low, high)
Ausgabe
1 10

Probier es aus

Was ist das Ergebnis?

Die Funktion berechnet 20 % Mehrwertsteuer auf den Preis. Was gehört in die Lücke, damit der Aufrufer das Ergebnis bekommt?

def vat(price):
     price * 0.2

Probier es aus

Zurückgegeben, aber verloren

Was gibt das Programm aus?

def reserve(seats):
seats = seats - 2
print(f"drinnen: {seats}")
return seats
seats = 10
reserve(seats)
print(f"draußen: {seats}")
Antwort

Die Idee

return beendet die Funktion

Der Shop berechnet für Bestellungen ab 50 € keine Lieferung. Sonst kostet die Lieferung 4,99 €:

def shipping_cost(total):
if total >= 50:
return 0
return 4.99
print(shipping_cost(62.0))
print(shipping_cost(18.5))
Ausgabe
0
4.99

Sobald return erreicht ist, endet die Funktion sofort. Deshalb läuft bei 62 € das zweite return nicht, und wir brauchen kein else.

Eine Funktion mit Ergebnis muss auf jedem Weg einen Wert zurückgeben. Aber Python prüft das nicht. Entfernst du die letzte Zeile, läuft das Programm, und bei einer Bestellung von 18,50 € erreicht die Funktion ihr Ende ohne return und gibt None zurück:

def shipping_cost(total):
if total >= 50:
return 0
print(shipping_cost(62.0))
print(shipping_cost(18.5))
Ausgabe
0
None

Es gibt keine Fehlermeldung, deshalb ist so ein Versehen schwer zu finden. Achte auf die Ausgabe und probier jeden Weg durch die Funktion aus.

Probier es aus

Finde den Fehler

Clubmitglieder bekommen 10 % Rabatt, alle anderen zahlen den vollen Preis. Aber alle bekommen den Rabatt. In welcher Zeile ist der Fehler?

Wähle die Zeile mit dem Fehler.

Übung

Funktionen, die rechnen

Löse die Aufgaben in deinem Editor. Jede Funktion bekommt, was sie braucht, als Parameter und gibt das Ergebnis zurück. Die Ausgabe passiert außerhalb der Funktionen, in den Zeilen darunter.

1. Durchschnitt. Die Funktion average(values) gibt den Durchschnitt der Zahlen in der Liste zurück. Lies darunter von der Tastatur ein, wie viele Zahlen es gibt, und dann die Zahlen selbst.

Eingabe
5
10
15
20
25
30
Ausgabe
Durchschnitt: 20.0

2. Primzahl. Die Funktion is_prime(n) gibt zurück, ob die Zahl eine Primzahl ist (nur durch 1 und durch sich selbst teilbar). Für 7 gibt sie True zurück, für 12 False.

3. Temperaturen. Die Funktionen to_fahrenheit(c) und to_celsius(f). F = C · 9 / 5 + 32. Lies eine Temperatur und eine Einheit (C oder F) ein und gib die umgerechnete aus.

Eingabe
100
C
Ausgabe
100.0 C = 212.0 F

4. Taschenrechner. Die Funktion calculate(a, b, op) gibt das Ergebnis für +, -, * oder / zurück. Die Rechenart wird mit if gewählt.

Eingabe
10
5
+
Ausgabe
10.0 + 5.0 = 15.0

5. Ein Dreieck mit Parameter. Wir haben es in der letzten Lektion versprochen. Die Funktion print_triangle(height) gibt ein rechtwinkliges Dreieck aus Sternchen mit der Höhe height aus. Für 3:

Ausgabe
*
* *
* * *
Genauer, für Neugierige

In Python liefert / immer eine Dezimalzahl, also ist 5 / 9 0,5555… und nicht 0 wie in Java und C#. Ganzzahldivision ist //:

print(5 / 9)
print(7 // 2)
Ausgabe
0.5555555555555556
3

Übung

Funktionen für Listen

Jede Aufgabe ist eine Funktion, die eine Liste (oder ein Wort) bekommt und ein Ergebnis zurückgibt. Am Ende setzt du alle zu einem Programm zusammen.

  1. total, sum_even und sum_odd: die Summe aller Zahlen, der geraden und der ungeraden in der Liste.
  2. reverse: gibt eine neue Liste mit den Zahlen in umgekehrter Reihenfolge zurück.
  3. largest und smallest: die größte und die kleinste Zahl.
  4. is_palindrome(word): ob das Wort vorwärts und rückwärts gleich gelesen wird.
  5. sum_diagonals und sum_diagonals_once: die Summe entlang beider Diagonalen einer quadratischen Matrix, wobei das mittlere Element zweimal bzw. einmal gezählt wird.
  6. Alles zusammen: für die Liste [1, 2, 3, 4, 5], die Zahl 7 (mit is_prime aus der Karte darüber), die Wörter „neben“ und „ABCDE“ und die 3 × 3-Matrix mit den Zahlen von 1 bis 9.

In Python sind sum, max und min schon eingebaute Funktionen. Nennst du deine eigene Funktion sum, verdeckt sie die eingebaute im ganzen Programm. Deshalb heißen unsere total, largest und smallest.

Ausgabe von Aufgabe 6
Summe: 15, Gerade: 6, Ungerade: 9
Umgekehrt: [5, 4, 3, 2, 1]
Max: 5, Min: 1
7 ist eine Primzahl: True
neben: True, ABCDE: False
Summe mit Wiederholung: 30, Summe ohne Wiederholung: 25

Test

Teste dich

1. Was ist in def vat(price): der Parameter?
2. Eine Funktion gibt ihrem Parameter einen neuen Wert. Was passiert mit der Variable, die du beim Aufruf übergeben hast?
3. Was macht return?
4. Eine Funktion erreicht ihr Ende, ohne an einem return vorbeizukommen. Was gibt sie zurück?
5. Was macht die Zeile price = apply_discount(price)?

Erstellt von Ivo Gergov im Rahmen der Kampagne von Evo Tech für zugängliche Programmierausbildung ·