0%

Ausdrucksstärkere Funktionen · Übung

Benenne wichtige Argumente ausdrücklich

Die vorige Lektion hat gezeigt, dass Schlüsselwortargumente einen Funktionsaufruf leichter lesbar machen können. Wir haben uns für status="needs review" entschieden, statt einen weiteren unerklärten String zu übergeben.

Schlüsselwortargumente waren aber nur eine Möglichkeit. Python würde die Positionsvariante weiterhin akzeptieren. Bei manchen Einstellungen möchten wir die Namen lieber verlangen.

Betrachte eine Funktion, die eine eingegebene Antwort auf zwei verschiedene Arten bereinigen kann:

def normalize_response(
    response,
    ignore_case=False,
    trim_spaces=True,
):
    ...

Versuche, diesen Aufruf zu lesen, ohne zur Definition zurückzugehen:

normalize_response("  Python  ", True, False)

Die beiden booleschen Werte erklären sich nicht selbst. Bedeutet True „Groß- und Kleinschreibung ignorieren“ oder „Leerzeichen entfernen“? Um das zu beantworten, musst du die Funktionsdefinition finden und jede Position sorgfältig zuordnen.

Verlange die Namen der Einstellungen

Python erlaubt uns, in der Funktionsdefinition * vor die Einstellungen zu setzen:

def normalize_response(
    response,
    *,
    ignore_case=False,
    trim_spaces=True,
):
    ...

Das * teilt die Parameter in zwei Gruppen:

  • response steht vor * und darf daher weiterhin nach Position übergeben werden.

  • ignore_case und trim_spaces stehen nach *, daher sind ihre Namen erforderlich.

Parameter, deren Namen erforderlich sind, heißen reine Schlüsselwortparameter oder keyword-only parameters. Der lesbare Aufruf ist jetzt die einzige gültige Form:

normalize_response(
    "  KEEP CASE  ",
    ignore_case=False,
    trim_spaces=True,
)

Das * erhält keinen Wert. Es ändert nur, wie spätere Argumente übergeben werden müssen. Der Funktionskörper kann ignore_case und trim_spaces weiterhin als gewöhnliche boolesche Werte verwenden.

Wenn du eine reine Schlüsselworteinstellung nach Position übergibst, entsteht ein TypeError, bevor der Funktionskörper läuft.

Verwende diese Regel, wenn die Namen Klarheit schaffen

Namen zu verlangen ist besonders hilfreich bei:

  • booleschen Schaltern;

  • mehreren Einstellungen mit demselben Werttyp;

  • optionalen Entscheidungen, die das Verhalten einer Funktion merklich ändern.

Nicht jedes Argument braucht diese Regel. Ein kurzer Aufruf wie round(3.14159, 2) ist bereits vertraut und kompakt. Reine Schlüsselwortparameter helfen, wenn die zusätzlichen Namen einen Aufruf deutlich verständlicher machen.

Was passiert, wenn die letzte Zeile ausgeführt wird?

def clean(text, *, lowercase=False):
    if lowercase:
        return text.lower()
    return text


print(clean("Python", True))

Der gültige Aufruf lautet clean("Python", lowercase=True).

Korrigiere einen ungültigen Aufruf

Die Funktion im Editor ist bereits vollständig, aber der aufrufende Code übergibt beide Einstellungen nach Position. Führe den Startcode aus und lies den TypeError. Korrigiere dann den Aufruf, indem du die beiden reinen Schlüsselwortargumente benennst. Die ausgegebenen Zeichen | machen verbleibende Leerzeichen sichtbar.

Behalte das * in der Funktionsdefinition bei. Es zu entfernen würde den Fehler verbergen, statt den unklaren Aufruf zu korrigieren.

Aufgabe

Führe den Startcode aus und untersuche seinen TypeError. Korrigiere dann den Aufruf, der result erstellt.

  • Behalte response als Positionsargument bei.

  • Übergib ignore_case=True als Schlüsselwortargument.

  • Übergib trim_spaces=False als Schlüsselwortargument.

  • Lass das *, den Funktionskörper und das abschließende print unverändert.

Das korrigierte Programm sollte | python | ausgeben. Die Striche sind nur Begrenzungen; die beiden Leerzeichen auf jeder Seite von python gehören zu result.