开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜