Appel D'une fonction Python avec les arguments *args,**kwargs et les arguments optionnels / par défaut

en python, je peux définir une fonction comme suit:

def func(kw1=None,kw2=None,**kwargs):
   ...

dans ce cas, je peux appeler func comme:

func(kw1=3,kw2=4,who_knows_if_this_will_be_used=7,more_kwargs=Ellipsis)

je peux aussi définir une fonction comme:

def func(arg1,arg2,*args):
    ...

que l'on peut appeler

func(3,4,additional,arguments,go,here,Ellipsis)

enfin, je peux combiner les deux formulaires

def func(arg1,arg2,*args,**kwargs):
    ...

mais, ce qui ne fonctionne pas s'appelle:

func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs):  #SYNTAX ERROR (in python 2 only,  apparently this works in python 3)
    ...

My à l'origine, on pensait que c'était probablement parce qu'une fonction

def func(arg1,arg2,*args,kw1=None):
    ...

peut être appelé comme

func(1,2,3) #kw1 will be assigned 3

donc cela introduirait une certaine ambiguïté quant à savoir si le 3 devrait être emballé dans des args ou des kwargs. Cependant, avec python 3, Il y a la possibilité de spécifier des arguments mot-clé seulement:

def func(a,b,*,kw=None):  #can be called as func(1,2), func(1,2,kw=3), but NOT func(1,2,3)
   ...

avec ceci, il semble qu'il n'y ait pas d'ambiguïté syntaxique avec:

def func(a,b,*args,*,kw1=None,**kwargs):
    ...

Cependant, cela provoque toujours une erreur de syntaxe (testée avec Python3.2). Y a-t-il une raison à ma disparition? Et, y a-t-il un moyen d'obtenir le comportement que j'ai décrit ci-dessus (ayant *args avec des arguments par défaut) -- je sais que je peux simuler ce comportement en manipulant le dictionnaire kwargs à l'intérieur de la fonction.

50
demandé sur Community 2012-03-26 17:16:27
la source

2 ответов

Vous peut faire que sur Python 3.

def func(a,b,*args,kw1=None,**kwargs):

Le nu * est utilisé uniquement lorsque vous souhaitez spécifier de mot-clé uniquement des arguments sans d'accepter un nombre variable d'arguments de position avec *args . Vous n'utilisez pas deux * s.

pour citer la grammaire, en Python 2, vous avez

parameter_list ::=  (defparameter ",")*
                    (  "*" identifier [, "**" identifier]
                    | "**" identifier
                    | defparameter [","] )

sur Python 3, vous avez

parameter_list ::=  (defparameter ",")*
                    (  "*" [parameter] ("," defparameter)*
                    [, "**" parameter]
                    | "**" parameter
                    | defparameter [","] )

qui comprend une disposition relative aux paramètres supplémentaires après le paramètre * .

50
répondu agf 2012-03-26 17:49:36
la source

si vous voulez faire un mélange des deux rappelez-vous que *args et **kwargs doivent être les derniers paramètres spécifiés.

def func(arg1,arg2,*args,kw1=None,kw2=None,**kwargs): #Invalid
def func(arg1,arg2,kw1=None,kw2=None,*args,**kwargs): #Valid

les commentaires semblent être basés sur un mélange de la façon dont une définition de fonction est construite et de la façon dont les arguments fournis sont attribués de nouveau aux paramètres spécifiés dans la définition.

C'est la définition de cette fonction, qui a 6 paramètres. Il est appelé en passant des arguments nommés et sans nom à dans un appel de fonction.

pour cet exemple... Quand un argument est nommé lors de l'appel de la fonction, il peut être fourni hors de l'ordre. arg1 et arg2 sont des paramètres obligatoires et s'ils ne sont pas passés à la fonction comme arguments nommés, alors ils doivent être assignés dans l'ordre à partir des arguments fournis sans nom. kw1 et kw2 ont des valeurs par défaut fournies dans la définition de la fonction de sorte qu'elles ne sont pas obligatoires, mais si elles ne sont pas fournies comme arguments nommés, elles prendront toutes les valeurs disponibles. des autres arguments fournis sans nom. Tous les arguments sans nom restants sont fournis à la fonction dans un tableau appelé args Tous les arguments nommés qui n'ont pas de nom de paramètre correspondant dans la définition de la fonction sont fournis à l'appel de fonction dans un dictionnaire appelé kwargs.

5
répondu frank 2018-03-01 05:55:12
la source

Autres questions sur