program story

* args 구문을 사용하는 인수 목록에서 후행 쉼표가 SyntaxError 인 이유는 무엇입니까?

inputbox 2020. 11. 5. 08:00
반응형

* args 구문을 사용하는 인수 목록에서 후행 쉼표가 SyntaxError 인 이유는 무엇입니까?


*argsPython에서 후행 쉼표를 사용할 수없는 이유는 무엇 입니까? 즉, 이것은 작동합니다

>>> 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의 경우입니다.


언어 사양을 살펴 보겠습니다 .

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에서는 작동하지 않습니다.


이전 답변에서 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기능을 사용하지 않는 경우 뒤에 쉼표를 사용할 수 있습니다 . 나는 이것이 절름발이라는 것에 동의합니다.


9232 호 에서이 버그에 대해 토론 한 후 Guido van Rossum 다음과 같이 댓글을 달았습니다 .

나는 이것을 추가하는 것에 대해 +1합니다. PEP가 필요하다고 생각하지 않습니다. 정의의 후행 쉼표는 이미 일부 지역에서 지원되므로 오류를 포착한다는 인수를 구입하지 않습니다. 유예 기간 동안 우리는 아마도 너무 엄격했을 것입니다.

그 후 Mark Dickinson의 패치가 적용되었습니다 . 따라서 이것은 이제 Python 3.6.0 알파 1에서 수정되었습니다.

참고 URL : https://stackoverflow.com/questions/16950394/why-is-a-trailing-comma-a-syntaxerror-in-an-argument-list-that-uses-args-syntax

반응형