args / kwargs的特殊用途

时间:2013-03-21 11:04:41

标签: python kwargs

我需要做这样的事情:

def func1(a, *args, b="BBB", **kwargs):
    print "a=%s b=%s args=%s kwargs=%s" % (a, b, args, kwargs)

所以这样打电话:

func1("AAAA", h="HHH", j="JJJ")

产生输出:

a=AAAA b=BBB args=() kwargs={'h': 'HHH', 'j': 'JJJ'}

但是不可能在*args之后放置默认的命名参数。 (SyntaxError: invalid syntax

  • 为什么不允许这样做?
  • 有没有可读的方法来实现这个?我知道的唯一方法是b=kwargs.pop("b", "BBB"),但这不是很易读。我更喜欢在它所属的函数调用定义中使用它:它是始终具有值的参数,默认值或用户给定的值。

修改

我可以将b放在args

前面
def func1(a, b="BBB", *args, **kwargs):
    print "a=%s b=%s args=%s kwargs=%s" % (a, b, args, kwargs)

但那意味着这个电话:

func1("AAAA", "CCC", h="HHH", j="JJJ")

"CCC"分配给b,我不想要。我希望b成为一个命名的arg,而不是一个可能的arg。

3 个答案:

答案 0 :(得分:2)

这在Python 3(demonstration)中完全有效; PEP 3102引入了仅限关键字的参数

在Python 2.x中,你必须继续使用kwargs.pop或适当的装饰者:

答案 1 :(得分:1)

In Python 2

  

当前的Python函数调用范例允许参数   由位置或关键字指定。可以填充一个参数   明确地按名称或隐含地按位置。

因此def func1(a, *args, b="BBB", **kwargs)含糊不清,因此不允许:在通话func1(1, 2)中,args == ()b == 2,或args = (2,)和{ {1}}?

这就是为什么b == "BBB"被接受的原因(即使它不能做你想做的事):def func1(a, b="BBB", *args, **kwargs)总是作为第二个参数传递,即使在像{这样的调用中也是如此{1}}(相当于b)。

正如ecatmur所说,Python 3改变了参数的处理方式,从而带来了您所需的灵活性。

答案 2 :(得分:0)

def func1(a, *args, **kwargs):
    b, k = (lambda b="BBBB", **k: b, k)(**kwargs)
    print "a=%s b=%s args=%s kwargs=%s" % (a, b, args, k)

可能是另一种选择。