同时使用可变长度参数和命名参数
我需要一些帮助来理解Python中的*args
和**kwargs
。这看起来很简单,但我还是没完全搞明白。这里有一个让我困惑的场景。
我有两个函数,mainfunc
和wrapperfunc
(后者是前者的包装函数)。它们的样子是这样的。
def mainfunc(fname=None, lname=None):
print 'Firstname: ' + fname
print 'Lastname: ' + lname
def wrapperfunc(uname, *args):
print uname
mainfunc(*args)
我可以这样调用wrapperfunc
:
wrapperfunc('j.doe', 'john', 'doe')
在这个方法中,所有三个参数都是位置参数。因为j.doe
被传给了uname
,所以其他两个参数可以通过*args
来访问。
但是,我能不能从一个字典中传递一些参数给wrapperfunc
,这样我就可以直接在wrapperfunc
中访问uname
,然后把剩下的位置参数传给mainfunc
呢?就像下面这个代码片段:
params = {'uname':'j.doe'}
wrapperfunc(**params, 'john', 'doe')
我想在wrapperfunc
中直接访问命名参数,但把所有的位置参数传给mainfunc
。
3 个回答
1
这可能就是你想要的:
def mainfunc(fname=None, lname=None):
print 'Firstname: ' + fname
print 'Lastname: ' + lname
def wrapperfunc(uname, *args, **kwargs):
print uname
mainfunc(*args, **kwargs)
然后在Python控制台里
>>> wrapperfunc('j.doe', 'john', lname='doe')
j.doe
Firstname: john
Lastname: doe
这样你就可以同时使用普通参数和关键字参数了。
1
你可以考虑使用装饰器函数。这里有一个来自Python文档的不错例子
这是我对你例子的看法。有没有什么特别的需求是这个不支持的呢?
def wrapper(function):
def closure(*args, **kwargs):
print kwargs.get('uname')
function(*args)
return closure
@wrapper
def mainFunc(fname, lname):
print 'Firstname:', fname
print 'Lastname:', lname
mainFunc('john', 'doe', uname='j.doe')
kw={'uname': 'j.doe_from_dict'}
mainFunc('john', 'doe', **kw)
5
在Python中,关键字参数必须放在位置参数后面。
params = {'uname':'j.doe'}
wrapperfunc('john', 'doe', **params)
这段代码会在两个位置参数之后传递关键字参数,
如果你想查看一个参数,但其他的调用正常进行,可以这样做:
def wrapper(*args, **kwargs):
print kwargs["uname"]
return mainfunc(*args, **kwargs)
你可以把这个方法推广到任何你想要的函数,作为一个装饰器使用。
def wrapper(f):
def wrapped(*args, **kwargs):
print kwargs["uname"]
return mainfunc(*args, **kwargs)
return wrapped
@wrapper
def foo(uname="Test"):
return uname + "bar"
# the @decorator is equivalent to `foo = wrapper(foo)`