web-dev-qa-db-ja.com

* args構文を使用する引数リストの末尾のコンマがSyntaxErrorであるのはなぜですか?

Pythonで*argsとともに末尾のコンマを使用できないのはなぜですか?言い換えれば、これは機能します

>>> 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の両方の場合です。

69
asmeurer

言語仕様 を見てみましょう:

_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
_

したがって、関数呼び出しへの引数の後、追加の_,_が許可されているように見えます。したがって、これはcpython実装のバグのように見えます。

f(1, *(2,3,4), )はこの文法に従って機能するはずですが、CPythonでは機能しません。


以前の回答では、 EricCPython文法仕様 にリンクされていました。これには、上記の文法の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_機能を使用しない場合、末尾にコンマを付けることができます。私はこれが不十分であることに同意します。

100
Bill Lynch

issue 9232 でこのバグに関するいくつかの議論の後、Guido van Rossum コメント

私はこれを追加することで+1です。 PEPが必要だとは思いません。定義の末尾のコンマはすでにいくつかの場所でサポートされているので、エラーをキャッチするという議論は買いません。モラトリアムの間、私たちはおそらく厳しすぎました。

その後、 Mark Dickinsonによるパッチ がコミットされました。したがって、これはPython 3.6.0 alpha1で修正されました。

6
BioGeek