Seite 1 von 1

Parameternamen und Argumentwerte zuordnen

Verfasst: Mittwoch 30. Juli 2008, 18:06
von sma
Meine Idee ist, bei einer Funktion per @-Attribut Typprüfungen für Parameter hinzuzufügen. Das Problem ist jedoch, den zu einem Parameternamen passenden Argumentwert zu finden.

Nehmen wir `def f(a, b=3)` als Beispiel. Diese Funktion kann ich auf verschiedene Weisen aufrufen:

Code: Alles auswählen

Aufruf       *args  **kwargs
f(1)         (1,)   {}
f(a=1)       ()     {'a': 1}
f(1, 2)      (1,2)  {}
f(1, b=3)    (1,)   {'b': 3}
f(b=1, a=2)  ()     {'a': 2, 'b': 1}
Ich habe außerdem notiert, wie die Parameter ankommen, wenn man die Funktion `def g(*args, **kwargs)` benutzt, um alle übergebenen Argumente zu erhalten, so wie man das auch in einer Wrapper-Funktion machen würde.

Muss ich jetzt selbst nach den gar nicht so einfachen Regeln von Python wieder die Zuordnung von Parameter und Argument herstellen oder gibt es da etwas fertiges?

Über `a = f.func_code.co_argcount` weiß ich, wie viele Argumente maximal gehen, wenn nicht `(f.func_code.co_flags & 12) != 0`. Über `f.func_defaults` kenne ich die Default-Werte und weiß, dass der erste Default-Parameter an Stelle `o = a - len(f.func_defaults)` liegt. Dies ist gleichzeitig die mimimale Argumentanzahl (außer `(f.func_code.co_flags & 12) != 0`). Den Wert für den N-ten Parameter finde ich in args, wenn len(args) < N. Ansonsten finde ich seinen Wert vielleicht in kwargs[f.func_code.co_varnames[N]] oder in f.func_defaults[N - o]. Gilt `flags & 12 == 4`, ist f.func_code.co_varnames[a] der Name des "*" Parameters und args[a:] sein Wert. Gilt `flags & 12 = 8`, ist f.func_code.co_varnames[a] der Name des **-Parameters, ansonsten ist es a+1. Sein Wert ist alles von kwargs ohne f.func_code.co_varnames[:a], so diese Schlüssel vorhanden.

Habe ich alle Fälle?

Stefan

Verfasst: Donnerstag 31. Juli 2008, 07:26
von audax