In Python kann für Funktionen vier Arten von Parametern deklariert werden: positionsabhängig, benannt (keyword), nur positionsabhängig (positional-only) und nur benannt (keyword-only). Ihr Unterschied beeinflusst die Art und Weise, wie Werte beim Aufruf von Funktionen übergeben werden.
/ deklariert (Python 3.8+), können nicht nach Namen angegeben werden.* deklariert, können nur nach Schlüssel angegeben werden.# Beispiel für alle Typen def func(a, b, /, c, *, d, e): print(a, b, c, d, e) func(1, 2, 3, d=4, e=5) # OK # func(a=1, b=2, 3, d=4, e=5) # Fehler: a, b - nur positionsabhängig
SyntaxError oder TypeError.*args sammelt zusätzliche Positionsparameter; **kwargs — benannte.Wie unterscheiden sich die Funktionsdeklarationen:
def f(a, b, c): ... def f(a, b, c=1): ... def f(a, b=1, c=2): ... def f(a=1, b=2, c=3): ...
und ist es wahr, dass man alle diese Funktionen sowohl mit positionsabhängigen als auch mit benannten Parametern aufrufen kann?
def f(a, b, c): kann man nicht nur mit benannten Argumenten aufrufen, da alle sowohl positionsabhängig als auch benannt übergeben werden können, aber alle Argumente sind erforderlich.def f(a, b, /, c): deklariert ist, können a und b nur positionsabhängig angegeben werden.def f(a, b, c=10): print(a, b, c) f(1, 2) # OK, c=10 standardmäßig f(a=1, b=2, c=3) # OK # Aber: def f(a, b, /, c=10): ... f(1, 2) # OK f(a=1, b=2, c=3) # Fehler! a und b nur positionsabhängig
Geschichte
Ein Entwickler implementierte eine Funktion, die gemäß Vereinbarung ausschließlich Parameter nach Namen annehmen sollte: Logging mit vielen Parametern, von denen einige optional sind. Aber sie vergaßen, * zu deklarieren — und Benutzer übergaben versehentlich Parameter in unterschiedlicher Reihenfolge positionsabhängig, was zu falscher Protokollierung und Fehlern führte, die schwer nachzuvollziehen sind.
Geschichte
In einem Projekt mit REST-API hörten aufgrund einer stillschweigenden Vereinbarung über die Reihenfolge der Argumente (verwendeten *args und schränkten benannte Parameter nicht ein) die Anfragen nach der Einführung einer neuen Clientversion auf zu arbeiten — weil sich args verschoben hatten. Dies wurde durch die Einführung expliziter * und die Angabe nur benannter Argumente behoben.
Geschichte
In einem großen Unternehmensprojekt wurde die Funktion um neue Parameter mit Standardwerten erweitert, aber aufgrund eines fehlerhaften Aufrufs mit positionsabhängigen Werten begann der alte Code, Werte in andere Parameter einzufügen, was zu einer unsachgemäßen Datenverarbeitung führte. Es stellte sich heraus, dass die Parameter nur benannt werden sollten.