为什么不能*args
在Python中使用尾随逗号?换句话说,这有效
>>> f(1, 2, b=4,)
但这不是
>>> f(*(1, 2), b=4,)
File "<stdin>", line 1
f(*(1, 2), b=4,)
^
SyntaxError: invalid syntax
Python 2和Python 3都是这种情况。
为什么不能*args
在Python中使用尾随逗号?换句话说,这有效
>>> f(1, 2, b=4,)
但这不是
>>> f(*(1, 2), b=4,)
File "<stdin>", line 1
f(*(1, 2), b=4,)
^
SyntaxError: invalid syntax
Python 2和Python 3都是这种情况。
f(*args,)
也不允许。
*args
,它是对这个原因感到好奇是合法的。如果您不同意,那么还有许多其他问题需要回答。
f(x=1, *(2, 3))
允许,但f(x=1, 2, 3)
不允许。f(1, 2, x=3,)
允许,但f(*(1, 2), x=3,)
不允许。
Answers:
让我们看一下语言规范:
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
让我们筛选一下我们关心的部分:
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
因此,看起来像在调用函数的任何参数之后,都允许有一个extra ,
。因此,这看起来像是cpython实现中的错误。
类似的东西:f(1, *(2,3,4), )
应该按照这种语法工作,但在CPython中却不行。
在较早的答案中,Eric链接到CPython语法规范,该规范包括上述语法的CPython实现。在下面:
arglist: (argument ',')* ( argument [',']
| '*' test (',' argument)* [',' '**' test]
| '**' test
)
请注意,这个语法是不一样的由语言规范提出的一个。我认为这是一个实现错误。
请注意,CPython实现还有其他问题。这也应该得到支持:f(*(1,2,3), *(4,5,6))
奇怪的是,该规范不允许 f(*(1,2,3), *(4,5,6), *(7,8,9))
当我进一步研究时,我认为规范的这一部分需要进行一些修复。这是允许的:f(x=1, *(2,3))
,但不是:f(x=1, 2, 3)
。
为了对原始问题有所帮助,在CPython中,如果不使用*args
或**kwargs
功能,可以使用逗号结尾。我同意这很la脚。
f(*(1,2,3), *(4,5,6))
“应该被支持”时您是什么意思-在我看来,语法(语言规范和cpython语法)都不允许这样做。
| "*" expression ["," "*" expression] ["," "**" expression]
。方括号中的第一个子句似乎错误地到达了该行,该行应为| "*" expression ["," "**" expression]
。正如sharth所说,规范确实需要一些工作。
在对问题9232中的错误进行了一些讨论之后,Guido van Rossum评论:
我对此加+1。我认为这不需要PEP。某些地方已经支持在定义中使用逗号结尾,因此我不赞成它捕获错误的说法。在暂停期间,我们也许太严格了。
随后,马克·迪金森(Mark Dickinson)提交了补丁。因此,这已在Python 3.6.0 alpha 1中修复。
(1,)
的可能会创建一个元组。