为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在使用* args语法的参数列表中尾随逗号是SyntaxError?

为什么在使用* args语法的参数列表中尾随逗号是SyntaxError?

蓝山帝景 2021-03-15 10:11:12
为什么不能*args在Python中使用尾随逗号?换句话说,这有效>>> f(1, 2, b=4,)但这不是>>> f(*(1, 2), b=4,)  File "<stdin>", line 1    f(*(1, 2), b=4,)                   ^SyntaxError: invalid syntaxPython 2和Python 3都是这种情况。
查看完整描述

2 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

让我们看一下语言规范:


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脚。


查看完整回答
反对 回复 2021-03-30
?
ibeautiful

TA贡献1993条经验 获得超5个赞

在对问题9232中的此错误进行了一些讨论之后,Guido van Rossum评论:

我对此添加+1。我认为这不需要PEP。某些地方已经支持定义中的逗号结尾,因此我不赞成它会捕获错误的说法。在暂停期间,我们也许太严格了。


查看完整回答
反对 回复 2021-03-30
  • 2 回答
  • 0 关注
  • 221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信