Que fait un astérisque nu dans les arguments d'une fonction?
Quand j'ai regardé le pickle module , je vois ceci:
pickle.dump(obj, file, protocol=None, *, fix_imports=True)
Je connais un astérisque simple et double précédant des arguments (pour un nombre variable d'arguments), mais cela ne précède rien. Et je suis sûr que cela n'a rien à voir avec cornichon. C'est probablement juste un exemple de ce qui se passe. J'ai appris son nom seulement quand j'ai envoyé ceci à l'interprète:
>>> def func(*):
... pass
...
File "<stdin>", line 1
SyntaxError: named arguments must follow bare *
Si cela compte, je suis sur python 3.3.0.
Nu *
est utilisé pour forcer l'appelant à utiliser des arguments nommés - vous ne pouvez donc pas définir de fonction avec *
en tant qu'argument lorsque vous n'avez pas d'argument de mot clé suivant.
Voir cette réponse ou documentation Python pour plus de détails.
Alors que la réponse originale répond complètement à la question, il suffit d'ajouter un peu d'informations connexes. Le comportement de chaque astérisque provient de PEP-3102
. Citant la section connexe:
The second syntactical change is to allow the argument name to
be omitted for a varargs argument. The meaning of this is to
allow for keyword-only arguments for functions that would not
otherwise take a varargs argument:
def compare(a, b, *, key=None):
...
En anglais simple, cela signifie que pour passer la valeur de la clé, vous devez explicitement la passer sous la forme key="value"
.
def func(*, a, b):
print(a)
print(b)
func("gg") # TypeError: func() takes 0 positional arguments but 1 was given
func(a="gg") # TypeError: func() missing 1 required keyword-only argument: 'b'
func(a="aa", b="bb", c="cc") # TypeError: func() got an unexpected keyword argument 'c'
func(a="aa", b="bb", "cc") # SyntaxError: positional argument follows keyword argument
func(a="aa", b="bb") # aa, bb
l'exemple ci-dessus avec ** kwargs
def func(*, a, b, **kwargs):
print(a)
print(b)
print(kwargs)
func(a="aa",b="bb", c="cc") # aa, bb, {'c': 'cc'}
J'ai trouvé le lien suivant très utile pour expliquer *
, *args
et **kwargs
:
https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/
En gros, en plus des réponses ci-dessus, j'ai appris sur le site ci-dessus (crédit: https://pythontips.com/author/yasoob008/ ) les éléments suivants:
Avec la fonction de démonstration définie ci-dessous, il y a deux exemples, l'un avec *args
et un avec **kwargs
def test_args_kwargs(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
# first with *args
>>> args = ("two", 3,5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5
# now with **kwargs:
>>> kwargs = {"arg3": 3, "arg2": "two","arg1":5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3
Alors *args
vous permet de construire de manière dynamique une liste d’arguments qui seront utilisés dans l’ordre dans lequel ils sont alimentés, alors que **kwargs
peut permettre la transmission des arguments NAMED et peut être traité par NAME en conséquence (quel que soit l'ordre dans lequel ils sont fournis).
Le site continue, notant que l'ordre correct des arguments doit être:
some_func(fargs,*args,**kwargs)