En quoi les "arguments de mots clés" sont-ils différents des arguments classiques? Tous les arguments ne peuvent-ils pas être passés sous la forme name=value
au lieu d'utiliser la syntaxe de position?
il existe deux concepts connexes, tous deux appelés "arguments de mots clés".
En ce qui concerne les appels, ce que d’autres commentateurs ont mentionné, vous avez la possibilité de spécifier certains 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 et 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 ceci:
def my_function(**kwargs):
print str(kwargs)
my_function(a=12, b="abc")
{'a': 12, 'b': 'abc'}
Il existe une dernière caractéristique linguistique où la distinction est importante. Considérons 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 mots-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)
Ils n'ont pas de mots-clés avant eux. L'ordre est important!
func(1,2,3, "foo")
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 aura de l'importance!
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'arguments positionnels, alors - oui - tout vous écrit s'avère être un argument 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 cela.
>>> 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
>>>
En utilisant Python 3, vous pouvez avoir les mots clés obligatoires/non requis 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
Required (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, surtout quand ils sont 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
( 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])
Cela 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 {}