为什么`def f(_,):传递一个有效的Python函数定义?

时间:2017-02-23 16:26:25

标签: python syntax

当我不小心输入

时,我在交互式控制台中编写了一些Python代码
def f(_, ): pass

但令我惊讶的是,解释员不会抱怨。我实际上意味着有两个伪参数,但如果第二个参数没有名称,为什么解释器会接受该函数?

2 个答案:

答案 0 :(得分:4)

看一下function definition syntax,您可以看到函数的参数列表具有以下语法:

parameter_list ::= defparameter ("," defparameter)* ["," [parameter_list_starargs]]
                   | parameter_list_starargs

这意味着,在完成位置参数后,您可以输入逗号并继续使用已命名或已加星标的参数(parameter_list_starargs);但实际上在最后一个逗号后面有逗号是可选的,所以在位置参数列表的末尾有一个额外的逗号是合法的。此外,查看parameter_list_starargs

的语法
parameter_list_starargs ::= "*" [parameter] ("," defparameter)* ["," ["**" parameter [","]]]
                            | "**" parameter [","]

可以看出,在最后一个命名参数之后还允许有一个额外的逗号。

作为一个侧面的句法注释,函数声明的一般语法是:

funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite

除其他外,它表示函数的annotation可以是任何表达式,实际上表示为有效的代码:

def f(_,) -> (lambda x, y: True): pass

答案 1 :(得分:1)

python接受尾随逗号是一般的事情,但它们并不被解释为表示另一个"匿名"要遵循的项目。他们刚刚被放弃

[1, 2, 3,] # legal: creates a three element list
{1, 2, 3,} # legal: creates a three element set
(1, 2, 3,) # legal: creates a three element tuple
1, 2, 3, # legal: creates a three element tuple
{1: 2, 3: 4,} # legal: creates a two item dict

当然,对于一个元素元组,实际上需要尾随逗号。

因此,不仅是函数定义(以及对此问题的调用)能够优雅地处理尾随逗号。

相关问题