[python] Kwargs en argument de fonction

a marqué ce sujet comme résolu.

Bonjour,

Je viens vous poser une question à laquelle je ne comprendrai certainement pas la réponse, mais sait-on jamais.

Il me semblait qu’en python, pour passer kwargs à une function, il fallait utilizer **kwargs.

J’ai voulu le faire avec la function odeint, de scipy. La syntaxe

1
odeint(eqdiff,conditions_ini,t,args=(point,**kwargs))

ne fonctionne pas. Par contre, les deux suivantes semblent fonctionner

1
2
odeint(eqdiff,conditions_ini,t,args=(point,kwargs))
odeint(eqdiff,conditions_ini,t,point,**kwargs)

À noter qu’avec la seconde, j’ai eu une erreur dans la function eqdiff, mais qui peut venir de moi.

C’est possible d’expliquer simplement pourquoi ?

Merci

La syntaxe **kwargs sert à décompacter (passer chacun de ses éléments comme argument nommé) un dictionnaire. Par exemple

1
2
3
4
5
6
def f(a=1, b=2, c=3):
    return a*b + c

dico = {"a":12, "b":42}
print( f(**dico) )
#renvoi 507 = 12 * 42 + 3

Au contraire, sans *, tu passes le dictionnaire complet en tant que dictionnaire.

Pour args, ça semble être un truc un peu bizarre dont je ne vois pas bien l’intérêt en python.

+0 -0

Bonjour,

kwargs, c’est juste un nom donné à une variable. Il est courant d’utiliser ce nom pour représenter, dans une fonction, le dictionnaire des arguments nommés.

Il s’accompagne logiquement de l’opérateur double-splat (**), qui permet de packer/unpacker les arguments nommés.

  • Lors de la définition d’une fonction :
1
def my_func(a, b, c, **kwargs): pass
  • Lors de l’appel
1
2
3
my_func(0, **{'d': 1, 'c': 2}, **{'e': 3, 'b': 4})

my_func(**kwargs)
  • Lors de la déclaration d’un dictionnaire
1
{'foo': 'bar', **kwargs}

Et c’est tout ce qui me vient en tête. Là, dans ton premier exemple, tu cherches à réaliser un double-splat dans un tuple, ce qui n’a pas de sens.

Je ne connais pas la fonction odeint, ce qu’elle doit faire et ce qu’elle attend comme paramètres. Mais si elle possède un paramètre args, c’est probablement qu’elle relaie un appel à une autre fonction. Dans ce cas il existe peut-être aussi un paramètre kwargs pour passer des arguments nommés à la fonction cible.

Merci à vous deux.

Là, dans ton premier exemple, tu cherches à réaliser un double-splat dans un tuple, ce qui n’a pas de sens

J’en déduis que

1
(0, **{'d': 1, 'c': 2})

est équivalent à

1
(0, 'd'= 1, 'c'=2})

et que ce sont les parties ’d’= qui posent problème dans le tuple.

Du coup, comment se fait-il que je puisse passer kwargs d’une fonction à une autre? Par exemple

1
2
def creep(**kwargs):
    creep_single(**kwargs)

Si le dictionnaire est unpacké la première fois, comment se fait-il qu’il existe encore ? Je concois volontiers que cette question puisse paraitre bête, mais j’ai besoin de bien comprendre la notion pour le boulot.

J’en déduis que

1
(0, **{'d': 1, 'c': 2})

est équivalent à

1
(0, 'd'= 1, 'c'=2})

et que ce sont les parties ’d’= qui posent problème dans le tuple.

Rockaround

Non. Le double-splat n’a de sens que dans les dictionnaires et dans les paramètres/arguments des fonctions. Il n’existe pas ailleurs, la grammaire ne reconnaît pas d’autre forme.

Mais f(0, **{'d': 1, 'c': 2}) est bien équivalent à f(0, d=1, c=2). Et {'a': 0, **{'d': 1, 'c': 2}} à {'a': 0, 'd': 1, 'c': 2}.

Du coup, comment se fait-il que je puisse passer kwargs d’une fonction à une autre? Par exemple

1
2
def creep(**kwargs):
    creep_single(**kwargs)

Si le dictionnaire est unpacké la première fois, comment se fait-il qu’il existe encore ? Je concois volontiers que cette question puisse paraitre bête, mais j’ai besoin de bien comprendre la notion pour le boulot.

Rockaround

** dans la liste des paramètres d’une fonction permet de récupérer le dictionnaire des arguments nommés. Le dictionnaire est donc créé à l’appel de la fonction, tous comme les valeurs des arguments sont assignées aux paramètres.

Dans le corps de la fonction, tu as donc une variable kwargs, tout à fait standard, qui contient un dictionnaire.

Comme c’est un dictionnaire, tu peux l’unpacker pour appeler une fonction.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte