我需要做这样的事情:
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。
答案 0 :(得分:2)
这在Python 3(demonstration)中完全有效; PEP 3102引入了仅限关键字的参数。
在Python 2.x中,你必须继续使用kwargs.pop
或适当的装饰者:
答案 1 :(得分:1)
当前的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)
可能是另一种选择。