Ich versuche, die folgende über den Umgang mit Funktionen und ihre Argumente zu verstehen:Legendes Funktionsargumente in Python
def print_my_arg(func, *args, **kwargs):
func(*args, **kwargs)
if 'my_arg' in kwargs:
print(' my_arg = {}'.format(kwargs['my_arg']))
def foo(call_no, my_arg='Default Value'):
print('call_no = {}'.format(call_no))
print_my_arg(foo, 0, my_arg='My Value 1')
print_my_arg(foo, 1, 'My Value 2')
print_my_arg(foo, 2)
Ausgang:
call_no = 0
my_arg = My Value 1
call_no = 1 # I'd like to see 'My Value 2' here
call_no = 2 # I'd like to see 'Default Value' here
Offensichtlich Menschen sind frei Funktionen entweder aufzurufen von die oben gezeigten Möglichkeiten, die mich wundern: warum my_arg
geht nicht auf kwargs
sowieso? Gibt es keinen einheitlichen Weg, um Parameter über den Namen (und nicht über die Position) zu erreichen, was nicht davon abhängt, wie die Funktion aufgerufen wurde?
Bitte beachten Sie, dass:
ich in
print_my_args(func, call_no, my_arg)
interessiert mich nicht, weil ich über den Fall zu sprechen bin, wo ich weiß nicht, die Unterschrift vonfunc
im Voraus und doch möchte ich wissen, ob ein bestimmter Parameter existiert (nach Name).Klar ist, dass an Dekorateure im Zusammenhang, aber ich habe das Beispiel in einer einfacheren Art und Weise geschrieben (oder hoffentlich).
EDIT
Vielen Dank für die Antworten zu inspect.signature. Mit, dass meine neue Version von print_my_arg()
ist:
from inspect import signature
def print_my_arg (func, *args, **kwargs):
func (*args, **kwargs)
sig = signature (func)
if 'my_arg' not in sig.parameters: return
binding = sig.bind (*args, **kwargs)
binding.apply_defaults()
print (" my_arg = {}".format (binding.arguments [ 'my_arg' ]))
Positional Argumente nicht * "go to "*' ** kwargs', weil * sie keine Schlüsselwort-Argumente * sind. Wenn Sie das zweite positionale Argument an die Funktion übergeben wollen, müssen Sie dies explizit tun, es ist überhaupt nicht klar, warum Sie ein anderes Verhalten erwartet haben. Sie könnten Schlüsselwortargumente erzwingen, wenn Sie wirklich möchten, siehe z. http://StackOverflow.com/a/37829651/3001761 – jonrsharpe
Möchten Sie die [Signatur] (https://docs.python.org/3/library/inspect.html?highlight=signature#inspect. Signature.bind) der Funktion zum Überprüfen des Argumentnamens in 'print_my_args'? dann könntest du 'passed_args = inspect.signature (func) .bind (* args, ** kwargs)' dann prüfen, ob 'my_arg' in' passed_args' ist. –
http://stackoverflow.com/questions/3394835/args-and-kwargs –