web-dev-qa-db-fra.com

Astérisque nu dans les arguments de la fonction?

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.

194
Eric

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.

185
Kimvais

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".

60
mu 無
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'}
10
laycat

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)
1
lb_so