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)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 = 3print_line(coffee, 2)Argumente werden den Parametern nach Position zugeordnet: das erste item, das zweite qty. Die Variable qty draußen hat nichts mit dem Parameter qty zu tun, obwohl sie gleich heißen.
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 = 100apply_discount(price)print(price) # 100100Der 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 = 100apply_discount(price)print(price) # 100Schritt für Schritt, in Worten
- Im Programm gibt es eine Variable price = 100.
- Du rufst apply_discount(price) auf: Für die Funktion wird neuer Speicher bereitgestellt.
- Ihr Parameter price bekommt den Wert 100.
- Die Funktion rechnet 100 * 0.9 = 90 aus und speichert die neue Zahl in ihrem eigenen price.
- Die Funktion endet, und ihr Speicher verschwindet, zusammen mit ihrem price.
- 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)['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 = 100price = apply_discount(price)print(price) # 90.0Schritt für Schritt, in Worten
- Im Programm: price = 100.
- Du rufst apply_discount(price) auf: Für die Funktion wird Speicher bereitgestellt.
- Der Parameter price bekommt den Wert 100.
- return price * 0.9: Das Ergebnis ist 90.
- Das Ergebnis geht zurück ans Programm und wird in price gespeichert.
- 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
returngibt 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))None- Du kannst
returnauch ohne Wert schreiben. Es beendet einfach die Funktion.
- Eine Funktion kann mehrere Werte auf einmal zurückgeben: Du zählst sie nach
returnmit Kommas auf und speicherst sie beim Aufruf in ebenso vielen Variablen:
def get_limits(): return 1, 10
low, high = get_limits()print(low, high)1 10Probier 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.2return: Ohne es rechnet die Funktion price * 0.2 aus und wirft das Ergebnis weg, und der Aufruf liefert None.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 = 10reserve(seats)print(f"draußen: {seats}")Die Funktion ändert ihre eigene Variable und gibt 8 zurück, aber niemand speichert das Ergebnis. Um es zu behalten, brauchst du seats = reserve(seats).
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))04.99Sobald 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))0NoneEs 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.
Das letzte return ist für alle, die keine Mitglieder sind: Sie zahlen den vollen Preis, return price.
Ü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.
51015202530Durchschnitt: 20.02. 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.
100C100.0 C = 212.0 F4. Taschenrechner. Die Funktion calculate(a, b, op) gibt das Ergebnis für +, -, * oder / zurück. Die Rechenart wird mit if gewählt.
105+10.0 + 5.0 = 15.05. 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:
** ** * *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)0.55555555555555563Ü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.
total,sum_evenundsum_odd: die Summe aller Zahlen, der geraden und der ungeraden in der Liste.reverse: gibt eine neue Liste mit den Zahlen in umgekehrter Reihenfolge zurück.largestundsmallest: die größte und die kleinste Zahl.is_palindrome(word): ob das Wort vorwärts und rückwärts gleich gelesen wird.sum_diagonalsundsum_diagonals_once: die Summe entlang beider Diagonalen einer quadratischen Matrix, wobei das mittlere Element zweimal bzw. einmal gezählt wird.- Alles zusammen: für die Liste
[1, 2, 3, 4, 5], die Zahl 7 (mitis_primeaus 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.
Summe: 15, Gerade: 6, Ungerade: 9Umgekehrt: [5, 4, 3, 2, 1]Max: 5, Min: 17 ist eine Primzahl: Trueneben: True, ABCDE: FalseSumme mit Wiederholung: 30, Summe ohne Wiederholung: 25Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Schleifen · Listen · Zweidimensionale Arrays · Funktionen
- Geht weiter in: Standardwerte · Rekursion · Klassen und Objekte · Konstruktoren und self
- Aufgaben zum Thema: Funktionen