Regardons les spécification du langage :
call ::= primary "(" [argument_list [","]
| expression genexpr_for] ")"
argument_list ::= positional_arguments ["," keyword_arguments]
["," "*" expression] ["," keyword_arguments]
["," "**" expression]
| keyword_arguments ["," "*" expression]
["," "**" expression]
| "*" expression ["," "*" expression] ["," "**" expression]
| "**" expression
positional_arguments ::= expression ("," expression)*
keyword_arguments ::= keyword_item ("," keyword_item)*
keyword_item ::= identifier "=" expression
Passons en revue les parties qui nous intéressent :
call ::= primary "(" [argument_list [","]] ")"
argument_list ::= positional_arguments ["," keyword_arguments]
["," "*" expression] ["," keyword_arguments]
["," "**" expression]
positional_arguments ::= expression ("," expression)*
keyword_arguments ::= keyword_item ("," keyword_item)*
keyword_item ::= identifier "=" expression
Donc, il semble qu'après tout argument d'un appel de fonction, nous avons le droit à un supplément. ,
. Cela ressemble donc à un bogue dans l'implémentation de cpython.
Quelque chose comme : f(1, *(2,3,4), )
devrait fonctionner selon cette grammaire, mais ne le fait pas en CPython.
Dans une réponse précédente, Eric lié à la Spécification de la grammaire CPython qui comprend l'implémentation CPython de la grammaire ci-dessus. Le voici ci-dessous :
arglist: (argument ',')* ( argument [',']
| '*' test (',' argument)* [',' '**' test]
| '**' test
)
Notez que cette grammaire est pas la même chose comme celle proposée par la spécification du langage. Je considérerais cela comme un bug d'implémentation.
Notez qu'il existe des problèmes supplémentaires avec l'implémentation de CPython. Ceci devrait également être pris en charge : f(*(1,2,3), *(4,5,6))
Bizarrement, la spécification ne permet pas f(*(1,2,3), *(4,5,6), *(7,8,9))
En regardant de plus près, Je pense que cette partie de la spécification doit être corrigée. C'est autorisé : f(x=1, *(2,3))
mais ce n'est pas le cas : f(x=1, 2, 3)
.
Et pour répondre à la question initiale, en CPython, vous pouvez avoir une virgule de fin si vous n'utilisez pas l'attribut *args
ou le **kwargs
fonction. Je suis d'accord pour dire que c'est nul.