14

我正在学习在 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,并且bc认为是位置参数。

所以,我现在试图10ae调用时分配withPositionalArgs

withPositionalArgs(ae=10,b,c)

但是,我做不到。我得到错误:

SyntaxError: non-keyword arg after keyword arg

我的问题是:

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

4

3 回答 3

14

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

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

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

在 Python3 中,顺序已经放宽了。(例如,*args可以出现在函数定义中的关键字参数之前。)请参阅 PEP3102

于 2012-09-08T15:55:53.523 回答
4

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

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)则会抛出 a 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}

但是,我怀疑这不是最佳实践......

于 2012-09-08T16:47:43.767 回答
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)
于 2017-04-27T18:27:27.523 回答