3

我需要做这样的事情:

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。

4

3 回答 3

2

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

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

于 2013-03-21T11:12:22.243 回答
1

在 Python 2中,

当前的 Python 函数调用范例允许通过位置或关键字指定参数。参数可以通过名称显式填充,也可以通过位置隐式填充。

结果def func1(a, *args, b="BBB", **kwargs)是模棱两可的,因此是不允许的:在 call func1(1, 2), should args == ()and b == 2, or args = (2,)and b == "BBB"?

这就是为什么def func1(a, b="BBB", *args, **kwargs)is,另一方面,被接受(即使它没有做你想要的):b总是作为第二个参数传递,即使在像这样的调用中func1(1, c=3, b=2)(它相当于func1(1, 2, c=3))。

正如 ecatmur 所指出的,Python 3 改变了处理参数的方式,这带来了您需要的灵活性。

于 2013-03-21T11:22:38.100 回答
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)

可能是另一种选择。

于 2013-03-21T11:14:19.127 回答