web-dev-qa-db-fra.com

Python: passage de paramètres par nom avec kwargs

En python nous pouvons le faire:

def myFun1(one = '1', two = '2'):
    ...

Ensuite, nous pouvons appeler la fonction et passer les arguments par leur nom:

myFun1(two = 'two', one = 'one')

Aussi, nous pouvons le faire:

def myFun2(**kwargs):
    print kwargs.get('one', 'nothing here')

myFun2(one='one')

Je me demandais donc s'il était possible de combiner les deux méthodes comme:

def myFun3(name, lname, **other_info):
    ...

myFun3(lname='Someone', name='myName', city='cityName', otherInfo='blah')

En général, quelles combinaisons pouvons-nous faire?

Merci et désolé pour ma question stupide.

30
CodeArtist

L'idée générale est:

def func(arg1, arg2, ..., kwarg1=default, kwarg2=default, ..., *args, **kwargs):
    ...

Vous pouvez en utiliser autant que vous le souhaitez. * Et ** "Absorberont" toutes les valeurs restantes non comptabilisées autrement.

Les arguments positionnels (fournis sans valeurs par défaut) ne peuvent pas être fournis par mot-clé, et les arguments non par défaut ne peuvent pas suivre les arguments par défaut.

Remarque Python 3 ajoute également la possibilité de spécifier des arguments de mots clés uniquement en les ayant après *:

def func(arg1, arg2, *args, kwonlyarg=default):
    ...

Vous pouvez également utiliser * Seul (def func(a1, a2, *, kw=d):), ce qui signifie qu'aucun argument n'est capturé, mais tout ce qui suit est uniquement par mot clé.

Donc, si vous êtes en 3.x, vous pouvez produire le comportement souhaité avec:

def myFun3(*, name, lname, **other_info):
    ...

Ce qui permettrait d'appeler avec name et lname comme mot clé uniquement.

Notez qu'il s'agit d'une interface inhabituelle, qui peut être agaçante pour l'utilisateur - je ne l'utiliserais que dans des cas d'utilisation très spécifiques.

Dans 2.x, vous auriez besoin de le faire manuellement en analysant **kwargs.

27
Gareth Latty

Vous pouvez ajouter vos arguments nommés avec kwargs si les clés sont disponibles dans la fonction appelante. Il sera pris dans votre argument nommé sinon il sera pris par le dictionnaire kwargs

def add(a=1, b=2,**c): res = a+b for items in c: res = res + c[items] print(res)

add(2,3)

5

add(b=4, a =3)

7

add(a =1,b=2,c=3,d=4)

dix

Blockquote

0
balaji dileep kumar

C'est possible au moins pour Python 2.7. Les arguments des mots-clés sont assignés aux paramètres positionnels par leur nom, donc vous pouvez faire

In [34]: def func(name, lname, **kwargs):
    print 'name='+name, 'lname='+lname
    print kwargs
   ....:     

In [35]: func(lname='lname_val', name='name_val', city='cityName', otherInfo='blah')
name=name_val lname=lname_val
{'city': 'cityName', 'otherInfo': 'blah'}

Les documents officiels le disent ainsi: "Si des arguments de mot-clé sont présents, ils sont d'abord convertis en arguments de position, comme suit. Premièrement, une liste d'emplacements non remplis est créée pour les paramètres formels. S'il y a N arguments de position, ils sont placés dans les premiers N slots. Ensuite, pour chaque argument de mot clé, l'identifiant est utilisé pour déterminer le slot correspondant (si l'identifiant est le même que le premier nom de paramètre formel, le premier slot est utilisé, etc.). Si le slot est déjà rempli, une exception TypeError est levée. Sinon, la valeur de l'argument est placée dans le slot, le remplissant (même si l'expression est None, elle remplit le slot). " https://docs.python.org/2/reference/expressions.html#calls

0
user2745509