J'aimerais appeler une fonction dans python à l'aide d'un dictionnaire.
Voici du code:
d = dict(param='test')
def f(param):
print(param)
f(d)
Ceci imprime {'param': 'test'}
mais je voudrais qu'il imprime simplement test
.
J'aimerais que cela fonctionne de la même manière pour plus de paramètres:
d = dict(p1=1, p2=2)
def f2(p1, p2):
print(p1, p2)
f2(d)
Est-ce possible?
Je l'ai compris par moi-même à la fin. C'est simple, il me manquait juste l'opérateur ** pour décompresser le dictionnaire
Donc, mon exemple devient:
d = dict(p1=1, p2=2)
def f2(p1,p2):
print p1, p2
f2(**d)
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
Quelques détails supplémentaires qu'il serait peut-être utile de connaître (questions que j'avais après avoir lu ceci et que je suis allé tester):
Exemples:
Nombre 1: La fonction peut avoir des paramètres qui ne sont pas inclus dans le dictionnaire
In[5]: mydict = {'a': 100}
In[6]: myfunc(**mydict)
100 2
Nombre 2: Vous ne pouvez pas remplacer un paramètre déjà présent dans le dictionnaire
In[7]: mydict = {'a': 100, 'b': 200}
In[8]: myfunc(a=3, **mydict)
TypeError: myfunc() got multiple values for keyword argument 'a'
Numéro 3: Le dictionnaire ne peut pas avoir de paramètres qui ne sont pas dans la fonction .
In[9]: mydict = {'a': 100, 'b': 200, 'c': 300}
In[10]: myfunc(**mydict)
TypeError: myfunc() got an unexpected keyword argument 'c'
Comme demandé dans les commentaires, une solution à Number 3 consiste à filtrer le dictionnaire en fonction des arguments de mots clés disponibles dans la fonction:
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
Une autre option consiste à accepter (et à ignorer) les kwargs supplémentaires dans votre fonction:
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
Notez bien que vous pouvez utiliser des arguments de position, des listes ou des tuples de la même manière que kwargs. Voici un exemple plus avancé incorporant tout ce qui précède:
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}
En python, cela s'appelle "décompresser", et vous en trouverez un peu dans le tutorial . La documentation sur ça craint, je suis d'accord, surtout à cause de son utilité fantastique.
Voilà, ça marche - ça marche n'importe quel autre itérable:
d = {'param' : 'test'}
def f(dictionary):
for key in dictionary:
print key
f(d)