在位置参数之前使用默认参数

时间:2012-09-08 15:52:40

标签: python

我正在学习在python中使用位置参数,并试图在与默认参数混淆时看看它们是如何工作的: -

def withPositionalArgs(ae=9,*args):
    print 'ae= ', ae
    print 'args = ', args


a=1
b=2
c=[10,20]

withPositionalArgs(a,b,c)

这给了我输出:

ae=  1
args =  (2, [10, 20])

如您所见,a被视为ae传递的值,b以及c被视为位置参数。< / p>

所以,我现在正在尝试在调用10时为ae分配withPositionalArgs

withPositionalArgs(ae=10,b,c)

但是,我不能这样做。我收到错误:

SyntaxError: non-keyword arg after keyword arg

我的问题是:

我做得对吗?是否允许使用默认参数或在python函数中的位置参数之前使用一个好的做法?

3 个答案:

答案 0 :(得分:12)

在Python2中,不允许在位置参数之前放置具有默认值的参数。

必须首先使用位置参数,然后是具有默认值的参数(或者,在调用函数时,使用关键字参数),然后是*args,然后是**kwargs

函数定义和函数调用都需要此顺序。

在Python3中,订单已经放宽。 (例如,*args可以出现在函数定义中的关键字参数之前。)See PEP3102

答案 1 :(得分:3)

我认为我们应该区分默认值与传递任意参数/键值对。没有默认值的行为是相同的:

def f(ae,*args, **kwargs):
    print 'ae     = ', ae
    print 'args   = ', args
    print 'kwargs = ', kwargs

我们写这个的方式意味着第一个参数传递到元组f中的args,即f(1,2,3,a=1,b=2)(序列变为显式参数,* args,** kwargs 。)这里:ae = 1, args = (2,3), kwargs = {'a': 1, 'b': 2}

如果我们尝试传入f(1,2,3,a=1,ae=3),我们会抛出TypeError: f() got multiple values for keyword argument 'ae',因为ae的值会被尝试更改两次。

解决这个问题的一种方法是只在明确规定时设置ae,我们可以(在def线之后):

def g(*args, **kwargs):
    kwargs, kwargs_temp = {"ae": 9}, kwargs
    kwargs.update(kwargs_temp) #merge kwargs into default dictionary

此次g(1,2,3,a=1,ae=3)设置args=(1,2,3), kwargs={a=1,ae=3}

但是,我怀疑这不是最佳做法......

答案 2 :(得分:1)

Python3放松了订购。

现在您可以执行以下操作:

def withPositionalArgs(*args, ae=9):
    print('ae=', ae)
    print('args =', args)
a=1
b=2
c=[10, 20]
withPositionalArgs(a, b, c, ae=7)