2.15. Argumente

Eine Funktion kann auf verschiedene Arten aufgerufen werden, und ihre Parameter können in verschiedenen Formen deklariert werden. Die Kombinationen wirken zunächst einschüchternd; drei oder vier Muster decken in der Praxis fast alles ab.

2.15.1. Positions- und Schlüsselwortargumente

Der einfachste Aufruf übergibt Argumente nach Position – der erste Wert geht an den ersten Parameter, der zweite an den zweiten und so weiter:

def rect(x, y, w, h):
    return (x, y, w, h)

rect(10, 20, 100, 50)

Derselbe Aufruf kann Argumente nach Schlüsselwort übergeben, indem jeder Parameter explizit benannt wird:

rect(x=10, y=20, w=100, h=50)

Schlüsselwortargumente sind reihenfolgenunabhängig und machen Aufrufe selbstdokumentierend, auf Kosten von mehr Tippaufwand. Positions- und Schlüsselwortargumente können in einem einzigen Aufruf gemischt werden, aber jedes Positionsargument muss vor jedem Schlüsselwortargument stehen:

rect(10, 20, w=100, h=50)         # OK
rect(x=10, 20, 100, 50)           # SyntaxError

2.15.2. Standardwerte

Ein Parameter kann einen Standardwert deklarieren, der verwendet wird, wenn der Aufrufer keinen angibt:

def greet(name, greeting="hello"):
    print(greeting, name)

greet("Alice")                    # hello Alice
greet("Alice", "hi")              # hi Alice
greet("Alice", greeting="hey")    # hey Alice

Parameter mit Standardwerten müssen in der def-Zeile nach Parametern ohne Standardwerte stehen.

Warnung

Standardwerte werden einmal ausgewertet, wenn die def ausgeführt wird – nicht bei jedem Aufruf. Die Verwendung eines veränderlichen Standardwerts ([], {}) führt dazu, dass dasselbe Objekt von jedem Aufruf gemeinsam genutzt wird, der den Standardwert übernimmt. Verwenden Sie stattdessen None als Wächterwert:

def append_to(item, target=None):
    if target is None:
        target = []
    target.append(item)
    return target

2.15.3. Variable Länge: *args und **kwargs

Ein mit * vorangestellter Parameter sammelt alle übrigen Positionsargumente in einem tuple. Ein mit ** vorangestellter Parameter sammelt alle übrigen Schlüsselwortargumente in einem dict. Die üblichen Namen sind args und kwargs, aber jeder Bezeichner funktioniert:

def report(label, *values, **options):
    print(label, values, options)

report("temps", 21, 22, 23, unit="C", precision=1)

Ausgabe:

temps (21, 22, 23) {'unit': 'C', 'precision': 1}

Eine Funktion benötigt selten beides. Die häufigste Verwendung ist das Weiterleiten von Argumenten von einem Wrapper an einen inneren Aufruf:

def log_and_call(func, *args, **kwargs):
    print("calling", func.__name__)
    return func(*args, **kwargs)

Die spiegelbildliche Syntax an der Aufruf-Stelle entpackt ein Iterable in Positionsargumente (*) oder ein dict in Schlüsselwortargumente (**):

point = (10, 20, 100, 50)
rect(*point)                      # same as rect(10, 20, 100, 50)

kwargs = {"x": 10, "y": 20, "w": 100, "h": 50}
rect(**kwargs)                    # same as rect(x=10, y=20, ...)

2.15.4. Nur-Schlüsselwort-Parameter

Ein alleinstehendes * in der Parameterliste (nicht an einen Namen gebunden) markiert jeden folgenden Parameter als Nur-Schlüsselwort – der Aufrufer muss den Namen verwenden:

def crop(buffer, *, x, y, w, h):
    ...

crop(buffer, x=0, y=0, w=100, h=100)   # OK
crop(buffer, 0, 0, 100, 100)           # TypeError

Verwenden Sie dies für boolesche Flags und andere Argumente, bei denen ein nackter Wert an der Aufrufstelle nicht selbsterklärend wäre.