ProgrammierungBackend Entwickler

Wie funktioniert der Mechanismus zur Arbeit mit Positions- und Schlüsselargumenten (positional and keyword arguments) in Python? Welche Nuancen gibt es bezüglich der Reihenfolge der Argumente bei der Definition und dem Aufruf von Funktionen, und wozu dienen nur Positions- und nur benannte Parameter?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

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.

Arten von Parametern

  1. Positionsabhängige (normalerweise zuerst): Werte werden in der Reihenfolge übergeben, in der sie angegeben werden.
  2. Benannte: Werden explizit durch ihren Namen angegeben.
  3. Nur positionsabhängige: Werden vor dem Symbol / deklariert (Python 3.8+), können nicht nach Namen angegeben werden.
  4. Nur benannte: Werden nach * 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

Nuancen

  • Reihenfolge der Parameter: (only-positional) / (positional-or-keyword) * (only-keyword)
  • Bei fehlerhafter Reihenfolge der Argumente gibt es einen SyntaxError oder TypeError.
  • *args sammelt zusätzliche Positionsparameter; **kwargs — benannte.

Fangfrage.

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?

Antwort:

  • Für die Funktion 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.
  • Man kann Parameter nach Namen angeben, wenn sie nicht als nur positionsabhängig deklariert sind.
  • Wenn die Funktion als def f(a, b, /, c): deklariert ist, können a und b nur positionsabhängig angegeben werden.

Beispiel:

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

Beispiele für echte Fehler aufgrund fehlender Kenntnis der Nuancen des Themas


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.