Zum Inhalt
wannacode

Standardwerte

Kurz gesagt: Der Standardwert eines Parameters wird verwendet, wenn das Argument nicht übergeben wird; Python hat außerdem Schlüsselwortargumente, und *args nimmt beliebig viele Argumente.

Problem

Zwei Artikel, drei Artikel

Die Kasse muss die Preise der Artikel addieren. Manchmal sind es zwei, manchmal drei. Die Funktion meint in beiden Fällen dasselbe: „addieren“. In Java und C# macht man das mit zwei Methoden, die einen Namen und unterschiedlich viele Parameter haben. Du versuchst dasselbe:

def total(a, b):
return a + b
def total(a, b, c):
return a + b + c
print(total(2.5, 4.0, 1.5))
print(total(2.5, 4.0))
Ausgabe
8.0

Mit drei Argumenten funktioniert es. Mit zweien bricht das Programm ab:

Fehler
TypeError: total() missing 1 required positional argument: 'c'

Python sagt, dass total das c fehlt. Es ruft also die Funktion mit drei Parametern auf. Wo ist die erste geblieben?

Die Idee

Ein Name, eine Funktion

In Python ist def eine Anweisung wie jede andere. Sie läuft, wenn das Programm sie erreicht, und speichert die Funktion unter einem Namen. Ein zweites def mit demselben Namen speichert eine neue Funktion unter diesem Namen, und die alte geht verloren. Welches def vor dem Aufruf zuletzt kam, entscheidet, welche Funktion läuft.

Deshalb kennt Python kein Überladen: zwei Funktionen mit einem Namen, die sich in ihren Parametern unterscheiden, wie in Java und C#. Stattdessen kann eine Funktion unterschiedlich viele Argumente nehmen. Wie, siehst du auf den nächsten Karten.

def print_header():
print("Eckladen")
print_header()
def print_header():
print("Laden am Markt")
print_header()
Schritt für Schritt, in Worten
  1. def speichert die Funktion unter dem Namen print_header. Der Name zeigt auf sie.
  2. Ein Aufruf: Der Name zeigt auf die erste Funktion, und sie gibt „Eckladen“ aus.
  3. Das zweite def erzeugt eine neue Funktion und lässt denselben Namen auf sie zeigen. Die erste ist weg.
  4. Der zweite Aufruf: „Laden am Markt“.
  5. Es gibt einen Namen. Das letzte def, das das Programm erreicht hat, entscheidet, welche Funktion aufgerufen wird.

Probier es aus

Welche Funktion?

Was gibt das Programm aus?

def describe(x):
print(f"ganz: {x}")
def describe(x):
print(f"dezimal: {x}")
describe(5)
describe(5.0)
Antwort

Die Idee

Ein Standardwert

Eine Funktion reicht für zwei und für drei Artikel. Gib dem dritten Parameter einen Standardwert: Er wird verwendet, wenn das Argument nicht übergeben wird.

def total(a, b, c=0):
return a + b + c
print(total(2.5, 4.0))
print(total(2.5, 4.0, 1.5))
Ausgabe
6.5
8.0

c=0 bedeutet: Hat der Aufruf nur zwei Argumente, ist c gleich 0. Hat er drei, ist c das dritte.

In Python setzt man um das = eines Standardwerts keine Leerzeichen: c=0. So steht es im Stilleitfaden PEP 8.

Parameter mit Standardwert schreibt man nach denen ohne. Argumente werden den Parametern nach Position zugeordnet, also stehen die optionalen am Ende.

Genauer, für Neugierige

Der Standardwert wird einmal berechnet, wenn Python das def erreicht, nicht bei jedem Aufruf. Für Zahlen und Text spielt das keine Rolle. Aber eine Standardliste ist für alle Aufrufe dieselbe Liste:

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

Der zweite Aufruf setzt die Liste des ersten fort. Deshalb schreibt man für eine Standardliste None und legt die Liste in der Funktion an:

def add_item(item, cart=None):
if cart is None:
cart = []
cart.append(item)
return cart
print(add_item("Brot"))
print(add_item("Milch"))
Ausgabe
['Brot']
['Milch']

Probier es aus

Finde den Fehler

Das Programm startet nicht. Python bricht mit einem SyntaxError ab, bevor es auch nur eine Zeile ausführt. In welcher Zeile ist der Fehler?

Wähle die Zeile mit dem Fehler.

Die Idee

Schlüsselwortargumente

Ein Hotel nimmt Buchungen an. Eine Nacht ohne Frühstück ist am häufigsten, also sind beide Standardwerte:

def book(name, nights=1, breakfast=False):
print(f"{name}, Nächte: {nights}")
if breakfast:
print(" mit Frühstück")
book("Maria")
book("Jonas", 3)
book("Lena", breakfast=True)
book(nights=2, name="Felix")
Ausgabe
Maria, Nächte: 1
Jonas, Nächte: 3
Lena, Nächte: 1
mit Frühstück
Felix, Nächte: 2

Lena möchte Frühstück, aber nur eine Nacht. Die Nächte musst du nicht schreiben: breakfast=True übergibt das Argument mit Namen, direkt an den Parameter breakfast. Das nennt man ein Schlüsselwortargument (keyword argument). Mit Namen spielt die Reihenfolge keine Rolle: Felix übergibt beide Argumente mit Namen, in umgekehrter Reihenfolge.

Der Name muss genau stimmen. Ein falsch geschriebener Name rutscht nicht still durch, er hält das Programm an:

Fehler
book("Maria", night=2)
TypeError: book() got an unexpected keyword argument 'night'
Genauer, für Neugierige
  • Nach einem Schlüsselwortargument darf kein Argument ohne Namen kommen: book(name="Maria", 3) startet nicht („positional argument follows keyword argument“).
  • Schlüsselwortargumente machen einen Aufruf klarer, auch wenn du nichts überspringst: book("Jonas", nights=3) liest sich leichter als book("Jonas", 3).

Die Idee

Beliebig viele Argumente

Und wenn es fünf Artikel sind? Zwanzig? Du schreibst nicht für jeden einen Parameter. Du sagst, dass die Funktion beliebig viele Argumente nimmt:

def total(*prices):
result = 0
for p in prices:
result += p
return result
print(total(1.5, 2.0, 3.5, 4.0))
print(total(9.99))
print(total())
Ausgabe
11.0
9.99
0

Das Sternchen vor dem Namen (*prices) bedeutet: „Übergib so viele Werte, wie du willst.“ In der Funktion kommen sie als Tupel an: eine Folge wie eine Liste, die sich nicht ändern lässt. Ohne Argumente ist es leer.

def show(*prices):
print(prices)
show(1.5, 2.0)
Ausgabe
(1.5, 2.0)

Deshalb gibt auch print so viele Werte aus, wie du ihm gibst: Es ist eine Funktion, die beliebig viele Argumente nimmt.

print("Brot", "Milch", "Kaffee")
print(max(3, 8, 2))
Ausgabe
Brot Milch Kaffee
8
Genauer, für Neugierige
  • Es kann nur einen solchen Parameter geben. Die Parameter danach lassen sich nur mit Namen übergeben: def receipt(*prices, currency="€") ruft man mit receipt(2.5, 4.0, currency="EUR") auf.
  • Es gibt auch **options: Es sammelt die Schlüsselwortargumente in einem Dictionary. Du wirst es in fremdem Code sehen.

Probier es aus

Was fehlt?

def total(prices):
    result = 0
    for p in prices:
        result += p
    return result

Übung

Eine Funktion statt mehrerer

1. Die größte. Schreib eine Funktion, largest(*numbers), die die größte von beliebig vielen Zahlen zurückgibt.

Aufrufe
largest(3, 8)
largest(4, 9, 2)
largest(2.5, 1.5)
Ausgabe
8
9
2.5

2. Notendurchschnitt. Die Funktion average(*grades) gibt den Durchschnitt beliebig vieler Noten zurück, und ohne Noten gibt sie 0 zurück.

Aufrufe
average(5, 6, 4)
average(6, 5)
average()
Ausgabe
5.0
5.5
0

3. Eine Zeile auf dem Bon. print_line(item, qty) gibt „Kaffee x 2“ aus. Mach die Menge optional: Ohne sie ist sie 1.

Aufrufe
print_line("Kaffee", 2)
print_line("Croissant")
Ausgabe
Kaffee x 2
Croissant x 1

4. Kostenlose Lieferung. shipping_cost(total, free_from=50) gibt 0 zurück, wenn die Bestellung mindestens die Schwelle erreicht, sonst 4,99 €. Die Schwelle ist 50 €, außer es wird eine andere übergeben.

Aufrufe
shipping_cost(62.0)
shipping_cost(30.0)
shipping_cost(30.0, free_from=25)
Ausgabe
0
4.99
0

Test

Teste dich

1. In der Datei steht def total(a, b): und darunter def total(a, b, c):. Was passiert bei total(2, 3)?
2. def total(a, b, c=0): Was gibt total(2, 3) zurück?
3. Wie rufst du def book(name, nights=1, breakfast=False): auf, damit es Frühstück gibt und die Nächte bei 1 bleiben?
4. Was ist prices in def total(*prices):?
5. Was davon führt Python NICHT aus?

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