Lektionen des Moduls (2/4)
Standardparameter und Keyword-Argumente
Funktionsparameter können Standardwerte haben: Wenn der Aufrufer sie nicht übergibt, werden die Standardwerte verwendet. Du kannst eine Funktion auch aufrufen, indem du Parameter namentlich übergibst (Schlüsselwortargumente oder keyword arguments).
Standardparameter
def saluta(nome, saluto="Ciao"):
return f"{saluto}, {nome}!"
saluta("Ada") # 'Ciao, Ada!'
saluta("Ada", "Hello") # 'Hello, Ada!'Parameter mit Standardwerten müssen nach den Parametern ohne Standardwerte stehen:
def f(a, b=1): # OK
def f(a=1, b): # SyntaxErrorSchlüsselwortargumente
Du kannst Argumente namentlich und in beliebiger Reihenfolge übergeben, was den Aufruf lesbarer macht:
def crea_utente(nome, eta, attivo=True):
return {"nome": nome, "eta": eta, "attivo": attivo}
crea_utente("Ada", 36)
crea_utente(nome="Ada", eta=36, attivo=False)
crea_utente(eta=36, nome="Ada") # any order when all are keywordGoldene Regel: In einem Aufruf stehen positionelle Argumente VOR Schlüsselwortargumenten.
crea_utente("Ada", eta=36) # OK
crea_utente(nome="Ada", 36) # SyntaxError⚠️ Die Falle mit veränderlichen Standardwerten (mutable default)
Verwende NIEMALS ein veränderliches Objekt (Liste, Dictionary, Set) als Standardwert: Der Standardwert wird NUR EINMAL ausgewertet (wenn die Funktion definiert wird) und von allen Aufrufen gemeinsam genutzt.
def aggiungi(elemento, lista=[]): # BUG!
lista.append(elemento)
return lista
aggiungi(1) # [1]
aggiungi(2) # [1, 2] !!! not [2] as you'd expect
aggiungi(3) # [1, 2, 3]Das richtige Muster: Verwende None als Wächter und erstelle das Objekt intern:
def aggiungi(elemento, lista=None):
if lista is None:
lista = []
lista.append(elemento)
return listaDie Gefahr von veränderlichen Standardargumenten
Verwende niemals veränderliche Objekte (wie Listen oder Dictionaries) als Standardwerte für Parameter: zum Beispiel def add(x, my_list=[]). Der Standardwert wird nur einmal bei der Definition der Funktion ausgewertet, was bedeutet, dass nachfolgende Aufrufe genau dasselbe veränderliche Objekt teilen! Die beste Praxis ist die Verwendung von None:
def add(x, my_list=None):
if my_list is None:
my_list = []
my_list.append(x)
return my_listProbiere es aus
Definiere `power(base, exponent=2)`, das base ** exponent zurückgibt. Berechne `square = power(5)` und `cube = power(5, exponent=3)`. Evaluiere `(square, cube)`.
Hinweis anzeigen
return base ** exponent
Lösung nach 3 Versuchen verfügbar
Wiederholungsübung
Definiere `create_record(name, values=None)`, das eine neue leere Liste verwendet, wenn values gleich None ist. Füge 1 zu values hinzu und gib das Record-Dictionary {'name': name, 'values': values} zurück. Rufe es zweimal auf, ohne values zu übergeben, und weise die Ergebnisse `a` und `b` zu. Evaluiere `(a['values'], b['values'])`.
Hinweis anzeigen
Verwende None als Standardwert und erstelle die Liste innerhalb der Funktion.
Lösung nach 3 Versuchen verfügbar
Zusätzliche Herausforderung
Definiere eine Funktion `greet(name, message="Hello")` die den formatierten String `"{message}, {name}!"` zurückgibt. Teste die Funktion, indem du `greet("Bob")` als letzten Ausdruck aufrufst.
Hinweis anzeigen
Verwende einen Standardparameter message="Hello" und einen f-String für die zurückgegebene Begrüßung.
Lösung nach 3 Versuchen verfügbar