Guardiamo il language specification:
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
Raccogliamo le parti che ci interessano:
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
Quindi, sembra che dopo qualsiasi argomento a una chiamata di funzione, è consentito un ulteriore ,
. Quindi questo sembra un bug nell'implementazione di cpython.
Qualcosa come: f(1, *(2,3,4),)
dovrebbe funzionare secondo questa grammatica, ma non in CPython.
In una precedente risposta, Eric legata al CPython grammar specification, che include l'implementazione CPython della grammatica sopra. Eccolo qui sotto:
arglist: (argument ',')* (argument [',']
| '*' test (',' argument)* [',' '**' test]
| '**' test
)
nota, che questa grammatica è non è la stessa come quello proposto dalla specifica del linguaggio. Lo considererei un bug di implementazione.
Si noti che ci sono ulteriori problemi con l'implementazione CPython. Questo dovrebbe anche essere sostenuto: f(*(1,2,3), *(4,5,6))
Stranamente, però, la specifica non consente f(*(1,2,3), *(4,5,6), *(7,8,9))
Mentre guardo questo di più, penso che questo parte della specifica ha bisogno di qualche fissaggio. Questo è permesso: f(x=1, *(2,3))
, ma questo non è: f(x=1, 2, 3)
.
E per essere forse utile alla domanda iniziale, in CPython, si può avere una virgola finale se non si utilizza il *args
o la funzione **kwargs
. Sono d'accordo che questo è zoppo.
Qualcosa a che fare con il modo in cui '(1,)' crea una tupla forse. – TankorSmash
Apparentemente la parola chiave args è irrilevante. 'f (* args,)' è anche non consentito. – asmeurer
@TankorSmash Ma qui non c'è una tupla come '(' non appare in una posizione di espressione – user2246674