为什么我不能定义像fun一样的函数(** kwargs,* args)?

时间:2013-09-22 14:38:50

标签: python

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

3 个答案:

答案 0 :(得分:10)

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

有关该规则背后的基本原理的解释,想象一下,如果您正在为Python编写一个应该将给定脚本转换为字节码的编译器。

假设你有一个功能:

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

然后有人用以下方法调用该函数:

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

你看到了歧义吗?你应该如何判断程序员是否打算将最后一个'3'分配给最后一个剩余参数'a',或者如果他意味着将分配给'c'但是只是用{创建了一个拼写错误' {1}}实际上意味着c=1。如果你正在编写任何语言的语法规则,你不想明确定义一组规则,这样你就可以完全确定程序员想要做什么而不是猜测程序员想要什么办?

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

答案 1 :(得分:2)

我认为这是因为命名参数的概念与可选参数的概念相混淆。当您使用可选参数(如def drawLine(x1, y1, x2, y2, color=Color.BLACK, width=1))定义函数时,所有可选参数都必须位于列表的末尾 - 否则,如果您有多个可选参数,那么该值是可选参数的不明确必要的论点。如果你随后用drawLine(x1=1, x2=2, 3,4,1)调用drawLine,哪个参数与哪个参数一起调用?因此,为了理智,首先放置位置参数,然后是命名参数。从概念上的一致性角度来看,以相同的顺序声明* args和** kwargs是有意义的。

答案 2 :(得分:1)

它实际上在documentation(我强调)中明确定义:

  

通常,参数列表必须具有任何位置参数   后跟任何关键字参数,其中必须选择关键字   来自形式参数名称。一个正式的并不重要   参数是否具有默认值。没有参数可以获得价值   不止一次 - 与位置对应的形式参数名称   参数不能在同一个调用中用作关键字。

     

[...]

     

当存在**name形式的最终形式参数时,它   接收包含所有关键字参数的字典,除了   对应于形式参数的那些。这可以与a结合使用   形式*name的形式参数(在下面描述   子部分)接收包含位置参数的元组   超出正式参数列表。 *name必须在之前发生   **name。)