2

当许多 python 书籍介绍它们时,args 总是在 kwargs 之前。我只是交换了它们的位置,但解释器告诉我这是一个无效的语法。谁能解释一下?

4

3 回答 3

10

在关键字参数之后定义位置参数是违反 Python 的语法的。因此,定义一个首先接受关键字参数字典然后接受位置参数元组的函数应该如何有意义?

为了解释规则背后的基本原理,想象一下如果你正在为 Python 编写一个编译器,它应该将给定的脚本翻译成字节码。

假设你有一个函数:

def func(a, b=2, c=3):
    print a,b,c

然后有人调用该函数:

func(c=1,b=2,3)

你看到歧义了吗?您应该如何判断程序员是否打算将最后一个“3”分配给最后一个剩余参数“a”,或者他是否打算将其分配给“c”,但只是打错了字c=1,实际上是a=1. 如果您正在为任何语言编写语法规则,您是否不想明确定义一组规则,以便您可以绝对确定程序员想要做什么,而不是猜测程序员想要做什么?

当然,我猜想有Interlisp和其他神秘的语言试图“猜测”程序员正在尝试做什么,但 Python 不是其中之一。

于 2013-09-22T15:05:53.113 回答
2

我认为这是因为命名参数的概念与可选参数的概念混为一谈。当您使用可选参数定义函数时,def drawLine(x1, y1, x2, y2, color=Color.BLACK, width=1)所有可选参数都必须位于列表的末尾 - 否则,如果您有多个可选参数,则哪个值是可选参数而不是必需参数将是模棱两可的。如果您然后调用 drawLine with drawLine(x1=1, x2=2, 3,4,1),哪些参数与哪个?因此,为了理智起见,将位置参数放在第一位,然后是命名参数。从概念一致性的角度来看,以相同的顺序声明 *args 和 **kwargs 才有意义。

于 2013-09-22T15:07:33.693 回答
1

它实际上在文档中非常明确地定义(我的重点):

通常,参数列表必须有任何位置参数,后跟任何关键字参数,其中关键字必须从形式参数名称中选择。形式参数是否具有默认值并不重要。任何参数都不能多次接收一个值——与位置参数相对应的形式参数名称不能用作相同调用中的关键字。

[...]

当表单的最终形式参数**name存在时,它会收到一个字典,其中包含所有关键字参数,除了与形式参数相对应的那些。这可以与形式*name(在下一小节中描述)形式的形式参数相结合,该形式参数接收包含超出形式参数列表的位置参数的元组。*name必须发生在之前 **name。)

于 2013-09-22T14:47:47.230 回答