我有以下代码:
def foo(func, *args, named_arg = None):
return func(*args)
返回SyntaxError
:
File "tester3.py", line 3
def foo(func, *args, named_arg = None):
^
为什么?是否有可能以某种方式定义一个函数,它接受一个参数(func
),然后在命名参数之前获取变量参数列表args
?如果没有,我的可能性是什么?
答案 0 :(得分:6)
全能*args
参数必须在任何显式参数之后:
def foo(func, named_arg=None, *args):
如果您还要将全部**kw
关键字参数添加到定义中,那么 会出现在*args
参数之后:
def foo(func, named_arg=None, *args, **kw):
混合使用显式关键字参数和catch-all *args
参数确实会导致意外行为;你不能同时使用任意位置参数和明确命名你同时列出的关键字参数。
func
以外的任何额外位置首先用于named_arg
,它也可以作为位置参数:
>>> def foo(func, named_arg = None, *args):
... print func, named_arg, args
...
>>> foo(1, 2)
1 2 ()
>>> foo(1, named_arg=2)
1 2 ()
>>> foo(1, 3, named_arg=2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for keyword argument 'named_arg'
>>> foo(1, 2, 3)
1 2 (3,)
这是因为foo()
的任何第二个位置参数将始终用于named_arg
。
在Python 3中,*args
参数可以放在关键字参数之前,但它具有 new 含义。通常,可以在呼叫签名中将关键字参数指定为位置参数(例如,将foo(somefunc, 'argument')
调用您的函数将'argument'
分配给named_arg
)。通过在位置参数和命名参数之间放置*args
或普通*
,可以排除命名参数用作位置参数;调用foo(somefunc, 'argument')
会引发异常。
答案 1 :(得分:2)
不,Python 2不允许这种语法。
您的选择是:
1)将命名的arg移动到*args
之前:
def foo(func, named_arg = None, *args):
...
2)使用**kwargs
:
def foo(func, *args, **kwagrs):
# extract named_arg from kwargs
...
3)升级到Python 3。
答案 2 :(得分:1)
将参数的顺序更改为:
def foo(func, named_arg = None, *args):
return func(*args)
答案 3 :(得分:1)
根据文件,没有:
教程section 4.7.2说:
在函数调用中,关键字参数必须遵循位置 参数。
...和4.7.3 says关于'任意参数列表':
在变量数量的参数之前,零或更多正常 争论可能会发生。
...所以如果你要使用所有三种参数类型,它们需要在序列中