Using variable length argument lists and named parameters together
I need some help with figuring out Pythons *args
and **kwargs
. It's simple but I haven't entire wrapped my head around them. Here's one of scenarios that's bewildering to me.
I have two functions mainfunc
and wrapperfunc
(which is a wrapper function for the main function). It looks like this.
def mainfunc(fname=None, lname=None):
print 'Firstname: ' + fname
print 'Lastname: ' + lname
def wrapperfunc(uname, *args):
print uname
mainfunc(*args)
I can call wrapperfunc
like this:
wrapperfunc('j.doe', 'john', 'doe')
In this method, all three parameters are positional. Since j.doe
comes into uname
, the other two params can be accessed by *args
..but is it possible to pass some of the params to wrapperfunc
from a dict so that I can still access uname
inside wrapperfunc
directly and then pass the remaining positional parameters to the m开发者_JS百科ainfunc
. Something like the following snippet:
params = {'uname':'j.doe'}
wrapperfunc(**params, 'john', 'doe')
I want to access the named parameters directly inside wrapperfunc
but pass all the positional parameters to mainfunc
.
Keyword arguments must come after position arguments in Python.
params = {'uname':'j.doe'}
wrapperfunc('john', 'doe', **params)
will pass the keyword arguments after the two positional arguments,
If you want to look at an argument, but otherwise do the call normally, do:
def wrapper(*args, **kwargs):
print kwargs["uname"]
return mainfunc(*args, **kwargs)
You can generalize this to work on any function you want as a decorator.
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)`
You should consider using a decorator function. Here's a nice example from the python docs
Here's my take on your example. Is there something specific this doesn't allow that you're looking for?
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)
This may be what you want:
def mainfunc(fname=None, lname=None):
print 'Firstname: ' + fname
print 'Lastname: ' + lname
def wrapperfunc(uname, *args, **kwargs):
print uname
mainfunc(*args, **kwargs)
And in the Python console
>>> wrapperfunc('j.doe', 'john', lname='doe')
j.doe
Firstname: john
Lastname: doe
This way you can mix both regular and keyword arguments.
精彩评论