it-swarm.com.de

Übergeben eines Wörterbuchs an eine Funktion als Schlüsselwortparameter

Ich möchte eine Funktion in python mit einem Wörterbuch aufrufen.

Hier ist ein Code:

d = dict(param='test')

def f(param):
    print(param)

f(d)

Dies druckt {'param': 'test'} aber ich möchte, dass es nur test druckt.

Ich möchte, dass es für weitere Parameter ähnlich funktioniert:

d = dict(p1=1, p2=2)
def f2(p1, p2):
    print(p1, p2)
f2(d)

Ist das möglich?

307
Dave Hillier

Am Ende habe ich es selbst herausgefunden. Es ist ganz einfach, mir hat nur der Operator ** gefehlt, um das Wörterbuch zu entpacken

So wird mein Beispiel:

d = dict(p1=1, p2=2)
def f2(p1,p2):
    print p1, p2
f2(**d)
473
Dave Hillier
In[1]: def myfunc(a=1, b=2):
In[2]:    print(a, b)

In[3]: mydict = {'a': 100, 'b': 200}

In[4]: myfunc(**mydict)
100 200

Einige zusätzliche Details, die hilfreich sein könnten (Fragen, die ich nach dem Lesen hatte und die ich getestet habe):

  1. Die Funktion kann Parameter haben, die nicht im Wörterbuch enthalten sind
  2. Sie können einen bereits im Wörterbuch enthaltenen Parameter nicht überschreiben
  3. Das Wörterbuch kann keine Parameter enthalten, die nicht in der Funktion enthalten sind.

Beispiele:

Nummer 1: Die Funktion kann Parameter haben, die nicht sind im Wörterbuch enthalten

In[5]: mydict = {'a': 100}
In[6]: myfunc(**mydict)
100 2

Nummer 2: Sie können einen Parameter, der ist, nicht überschreiben bereits im Wörterbuch

In[7]: mydict = {'a': 100, 'b': 200}
In[8]: myfunc(a=3, **mydict)

TypeError: myfunc() got multiple values for keyword argument 'a'

Nummer 3: Das Wörterbuch kann keine Parameter haben, die nicht vorhanden sind nicht in der Funktion.

In[9]:  mydict = {'a': 100, 'b': 200, 'c': 300}
In[10]: myfunc(**mydict)

TypeError: myfunc() got an unexpected keyword argument 'c'

Wie in Kommentaren gefordert, besteht eine Lösung für Nummer 3 darin, das Wörterbuch anhand der Schlüsselwortargumente zu filtern verfügbar in der Funktion:

In[11]: import inspect
In[12]: mydict = {'a': 100, 'b': 200, 'c': 300}
In[13]: filtered_mydict = {k: v for k, v in mydict.items() if k in [p.name for p in inspect.signature(myfunc).parameters.values()]}
In[14]: myfunc(**filtered_mydict)
100 200

Eine andere Möglichkeit besteht darin, zusätzliche kwargs in Ihrer Funktion zu akzeptieren (und zu ignorieren):

In[15]: def myfunc2(a=None, **kwargs):
In[16]:    print(a)

In[17]: mydict = {'a': 100, 'b': 200, 'c': 300}

In[18]: myfunc2(**mydict)
100

Beachten Sie, dass Sie Positionsargumente und Listen oder Tupel genauso effektiv verwenden können wie kwargs. Hier ist ein erweitertes Beispiel, das alles oben Genannte enthält:

In[19]: def myfunc3(a, *posargs, b=2, **kwargs):
In[20]:    print(a, b)
In[21]:    print(posargs)
In[22]:    print(kwargs)

In[23]: mylist = [10, 20, 30]
In[24]: mydict = {'b': 200, 'c': 300}

In[25]: myfunc3(*mylist, **mydict)
10 200
(20, 30)
{'c': 300}
95
David Parks

In Python wird dies als "Auspacken" bezeichnet, und Sie können ein wenig darüber im Tutorial nachlesen. Die Dokumentation ist zum Kotzen, ich stimme zu, vor allem, weil es phantastisch nützlich ist.

30
llimllib

Auf geht's - funktioniert so gut wie alles andere:

d = {'param' : 'test'}

def f(dictionary):
    for key in dictionary:
        print key

f(d)
6