2016-07-20 11 views
1

Ich habe eine Funktion mit einigen benannten Parametern und ein Wörterbuch, das Schlüssel mit diesen Namen sowie einige andere Schlüssel enthält. Ich möchte die Funktion mit Werten aus dem Wörterbuch aufrufen.Gibt es eine ordentliche (Python?) Möglichkeit, benannte Parameter Standardwerte in Python bei einer Bedingung zu verwenden?

  • Ich kann nicht **data verwenden, weil Python wird TypeError: unexpected keyword argument erhöhen wegen der zusätzlichen Tasten.
  • Das dict enthält möglicherweise keine Schlüssel, daher kann ich die Schlüssel nicht referenzieren, ohne zu überprüfen, ob sie existieren (und ich möchte keinen Standard von get übergeben).
  • Ich kann die Funktion nicht umschreiben, weil es in einer separaten Bibliothek ist.

Wie kann ich nur die Schlüssel entpacken, die den Funktionsparametern entsprechen?

def do_something(arg1=None, arg2=''): 
    ... 

data = {'arg1': 1, 'arg2': 2, 'other': 3} 

# doesn't work if key doesn't exist 
do_something(arg1=data['arg1'], arg2=data['arg2']) 

# too verbose, hard to extend 
if 'arg1' in data: 
    do_something(arg1=data['arg1'], arg2=data['arg2']) 
else: 
    do_something(arg2=data['arg2']) 
+0

'do_something (** d)'? – YOU

+1

Auch verwandt: http://stackoverflow.com/questions/1769403/understanding-kwargs-in-python – mgilson

+0

@YOU: Nein, das 'd' enthält mehr Schlüssel als diejenigen, die ich an die Funktion übergeben muss. –

Antwort

1

Alternativ grub ich ihn nur aus einem meiner Projekte

def call_with_optional_arguments(func, **kwargs): 
    ''' 
    calls a function with the arguments **kwargs, but only those that the function defines. 
    e.g. 

    def fn(a, b): 
     print a, b 

    call_with_optional_arguments(fn, a=2, b=3, c=4) # because fn doesn't accept `c`, it is discarded 
    ''' 

    import inspect 
    function_arg_names = inspect.getargspec(func).args 

    for arg in kwargs.keys(): 
     if arg not in function_arg_names: 
      del kwargs[arg] 

    func(**kwargs) 

In Ihrem Fall könnte es wie verwendet werden Wenn ich mich über den Namen wundere, benutzte ich das, um Callback-Funktionen auszulösen, die der Benutzer meiner Bibliothek weitergeben würde. "optional" bedeutet in diesem Fall, dass func nicht alle Argumente akzeptieren muss, die ich anrufe mit)

+0

danke @joerick. Ich hatte auf einen guten syntaktischen Zucker gehofft, aber es scheint, dass es keinen gibt. Ich denke, ich könnte eine Funktion schreiben, die meinen Bedürfnissen entspricht. –

1

Gerade hier Riffing ...

do_something(**{ k: data[k] for k in ['Arg1', 'Arg2'] if k in data }) 

dass, obwohl ziemlich böse aussieht.

(Wenn Sie‘-

call_with_optional_arguments(do_something, **data) 

: