为什么关键字args不能位于变量位置args之前?

时间:2014-08-30 18:59:57

标签: python

我正在使用python 3.3。考虑这个功能:

def foo(action, log=False,*args) :
    print(action)
    print(log)
    print(args)
    print()

以下调用按预期工作:

foo("A",True,"C","D","E")

A
True
('C', 'D', 'E')

但这个没有。

foo("A",log=True,"C","D","E")

SyntaxError: non-keyword arg after keyword arg

为什么会这样?
这是否会以某种方式引入歧义?

2 个答案:

答案 0 :(得分:6)

请考虑以下事项:

def foo(bar="baz", bat=False, *args):
    ...

现在如果我打电话

foo(bat=True, "bar")

“酒吧”去哪了?之一:

  • bar = "bar", bat = True, args = ()
  • bar = "baz", bat = True, args = ("bar",),甚至
  • bar = "baz", bat = "bar", args = ()

并且没有明显的选择(至少在前两个之间)它应该是哪一个。我们希望bat = True'消耗'第二个参数槽,但是不清楚剩下的参数应该用于哪个顺序:将它视为bat根本不存在并将所有内容移动到离开,或者将其视为bat将“光标”移到自己的下一个参数上。或者,如果我们想要做一些真正奇怪的事情,我们可以捍卫决定说参数元组总是中的第二个参数与第二个位置参数一起,无论是否传递了其他关键字参数。

无论如何,我们留下了一些令人困惑的东西,有人会惊讶我们选择哪一个而不管它是哪一个。 Python旨在简单而干净,并且希望避免任何可能不直观的语言设计选择。 There should be one-- and preferably only one --obvious way to do it

答案 1 :(得分:1)

关键字参数的功能有两个:

  1. 为不依赖参数顺序的函数提供接口。
  2. 提供一种在将参数传递给函数时减少歧义的方法。
  3. 当您在有序参数之前提供关键字参数时,提供关键字和有序参数的混合只是一个问题。这是为什么?

    有两个原因:

    1. 阅读令人困惑。如果您提供有序参数,为什么要标记其中一些而不是其他参数?
    2. 处理参数的算法将是不必要和复杂的。您可以在“有序”参数后提供关键字args。这是有道理的,因为很明显所有内容都有序,直到您使用关键字为止。然而;如果您在有序参数之间使用关键字,则没有明确的方法来确定您是否仍在订购参数。