Arguments normaux vs arguments de mots clés
-
07-07-2019 - |
Question
Comment sont les "arguments de mots clés" " différent des arguments habituels? Tous les arguments ne peuvent-ils pas être passés sous la forme name = value
au lieu d'utiliser la syntaxe de position?
La solution
il existe deux concepts connexes, appelés "arguments de mots clés".
Du côté des appels, ce que d'autres commentateurs ont mentionné, vous avez la possibilité de spécifier des arguments de fonction par nom. Vous devez les mentionner après tous les arguments sans nom (arguments de position), et il doit exister des valeurs par défaut pour tout paramètre non mentionné.
L’autre concept concerne la définition de la fonction: vous pouvez définir une fonction qui prend les paramètres par nom - et vous n’avez même pas à spécifier quels sont ces noms. Ce sont des mots-clés purs, qui ne peuvent pas être transmis positionnellement. La syntaxe est
def my_function(arg1, arg2, **kwargs)
Tous les arguments de mots clés que vous transmettez à cette fonction seront placés dans un dictionnaire nommé kwargs. Vous pouvez examiner les clés de ce dictionnaire au moment de l'exécution, comme suit:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
Autres conseils
Il existe une dernière fonctionnalité linguistique pour laquelle la distinction est importante. Considérez la fonction suivante:
def foo(*positional, **keywords):
print "Positional:", positional
print "Keywords:", keywords
L'argument * positional
stockera tous les arguments de position transmis à foo ()
, sans limitation du nombre que vous pouvez en fournir.
>>> foo('one', 'two', 'three')
Positional: ('one', 'two', 'three')
Keywords: {}
L'argument ** keywords
stockera tous les arguments de mots clés:
>>> foo(a='one', b='two', c='three')
Positional: ()
Keywords: {'a': 'one', 'c': 'three', 'b': 'two'}
Et bien sûr, vous pouvez utiliser les deux en même temps:
>>> foo('one','two',c='three',d='four')
Positional: ('one', 'two')
Keywords: {'c': 'three', 'd': 'four'}
Ces fonctionnalités sont rarement utilisées, mais elles sont parfois très utiles et il est important de savoir quels arguments sont positionnels ou clés.
Utiliser des arguments de mots clés revient au même que des arguments normaux, sauf que l'ordre n'a pas d'importance. Par exemple, les deux appels de fonctions ci-dessous sont les mêmes:
def foo(bar, baz):
pass
foo(1, 2)
foo(baz=2, bar=1)
Arguments de position
Ils n'ont pas de mots-clés devant eux. L'ordre est important!
func(1,2,3, "foo")
Arguments des mots clés
Ils ont des mots clés à l'avant. Ils peuvent être dans n'importe quel ordre!
func(foo="bar", baz=5, hello=123)
func(baz=5, foo="bar", hello=123)
Vous devez également savoir que si vous utilisez des arguments par défaut et que vous omettez d'insérer les mots-clés, l'ordre sera alors important!
def func(foo=1, baz=2, hello=3): ...
func("bar", 5, 123)
Il existe deux manières d'affecter des valeurs d'argument aux paramètres de fonction. Les deux sont utilisés.
-
Par position. Les arguments positionnels n'ont pas de mots-clés et sont attribués en premier.
-
Par mot clé. Les arguments de mots-clés ont des mots-clés et sont attribués en second, après les arguments de position.
Notez que vous avez la possibilité d'utiliser des arguments de position.
Si vous n'utilisez pas d'argument de position, alors - oui - tout ce que vous avez écrit s'avère être un argument de mot-clé.
Lorsque vous appelez une fonction, vous décidez d'utiliser une position, un mot clé ou un mélange. Vous pouvez choisir de faire tous les mots-clés si vous le souhaitez. Certains d’entre nous ne font pas ce choix et utilisent des arguments de position.
Je suis surpris que personne ne semble avoir signalé qu'il est possible de passer un dictionnaire de paramètres d'argument codés, qui satisfont les paramètres formels, comme ceci.
>>> def func(a='a', b='b', c='c', **kwargs):
... print 'a:%s, b:%s, c:%s' % (a, b, c)
...
>>> func()
a:a, b:b, c:c
>>> func(**{'a' : 'z', 'b':'q', 'c':'v'})
a:z, b:q, c:v
>>>
Avec Python 3 , vous pouvez utiliser les mots clés obligatoires et non obligatoires arguments :
Facultatif : (valeur par défaut définie pour 'b')
def func1(a, *, b=42):
...
func1(value_for_a) # b is optional and will default to 42
Obligatoire (aucune valeur par défaut définie pour 'b'):
def func2(a, *, b):
...
func2(value_for_a, b=21) # b is set to 21 by the function call
func2(value_for_a) # ERROR: missing 1 required keyword-only argument: 'b'`
Cela peut aider dans les cas où vous avez beaucoup d'arguments similaires les uns à côté des autres, en particulier lorsque vous êtes du même type. Dans ce cas, je préfère utiliser des arguments nommés ou créer une classe personnalisée si les arguments sont liés.
Je suis surpris que personne n'ait mentionné le fait que vous pouvez mélanger des arguments de position et de mot clé pour faire des choses sournoises comme celle-ci en utilisant * args
et ** kwargs
(< un href = "http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/" rel = "noreferrer"> à partir de ce site ):
def test_var_kwargs(farg, **kwargs):
print "formal arg:", farg
for key in kwargs:
print "another keyword arg: %s: %s" % (key, kwargs[key])
Ceci vous permet d'utiliser des arguments de mots clés arbitraires pouvant contenir des clés que vous ne souhaitez pas définir d'avance.
Je cherchais un exemple avec kwargs par défaut utilisant une annotation de type:
def test_var_kwarg(a: str, b: str='B', c: str='', **kwargs) -> str:
return ' '.join([a, b, c, str(kwargs)])
exemple:
>>> print(test_var_kwarg('A', c='okay'))
A B okay {}
>>> d = {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', c='c', b='b', **d))
a b c {'f': 'F', 'g': 'G'}
>>> print(test_var_kwarg('a', 'b', 'c'))
a b c {}