我尝试使用*和**将任意数量的参数传递给函数。在Mark Lutz撰写的“ Learning Python”中,它说首先要遵循位置(值)的顺序,然后是关键字参数(名称=值)和*序列的组合,然后是** dict。但是,我发现位置参数(如果存在)需要首先出现,但是在一定程度上可以将其余三个位置参数按顺序混合使用。
代码keyword3.py:
def func(a, b=1, *pArgs, **kwArgs):
print("a = {0}, b = {1}".format(a,b))
print("Positional args = {}".format(pArgs))
print("Keyword args = {}".format(kwArgs))
通过反复试验,
[1]在关键字和** dict之间,它们可以任意顺序...
>>> import keywords3 as j
>>> j.func(b = 3, **{'a':2,'c':4,'d':5})
a = 2, b = 3
Positional args = ()
Keyword args = {'d': 5, 'c': 4}
>>> j.func( **{'a':2}, b = 3, **{'c':4})
a = 2, b = 3
Positional args = ()
Keyword args = {'c': 4}
[2]在位置args和*序列之间,它们可以是任意顺序...
>>> j.func(*(2, 3), 4, *(5, 6))
a = 2, b = 3
Positional args = (4, 5, 6)
Keyword args = {}
>>> j.func(2, *(3, 4), 5, *(6,7), **{'c':8})
a = 2, b = 3
Positional args = (4, 5, 6, 7)
Keyword args = {'c': 8}
[3]通常,在关键字或** dict参数之前,必须出现位置或序列参数。
>>> j.func(*(3, 4), 5, *(6,7), d=15, **{'c':8}, e=16)
a = 3, b = 4
Positional args = (5, 6, 7)
Keyword args = {'e': 16, 'd': 15, 'c': 8}
>>> j.func(d=15, 5, *(6,7), **{'c':8}, e=16)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> j.func(**{'a':2}, 5, *(6,7), **{'c':8}, e=16)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument unpacking
>>> j.func(**{'a':2}, *(6,7), **{'c':8}, e=16)
File "<stdin>", line 1
SyntaxError: iterable argument unpacking follows keyword argument unpacking
[4]一个例外是关键字参数后面的可迭代参数解压缩*(6,7)没问题...
>>> j.func(f=5, *(6,7), **{'c':8}, e=16)
a = 6, b = 7
Positional args = ()
Keyword args = {'e': 16, 'f': 5, 'c': 8}
这些观察正确吗?请发表评论。
答案 0 :(得分:3)
有一个单个规则与您的所有示例都一致:位置参数位于命名参数之前。
在所有示例中,*
和**
是拆包运算符。例如,当您写
f(1, *(2,3), 4)
语言得到
f(1,2,3,4)
它们是所有位置参数,该语言不知道它们之间的区别。对于**
运算符也是如此。
但是,当您违反该唯一规则时,例如
j.func(**{'a':2}, 5, *(6,7), **{'c':8}, e=16)
由于出现错误,因为在此示例中,**{'a':2}
等效于a=2
,后者在位置参数5
之前。