2

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 mainfunc. 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.

3
  • 4
    It is not clear what exactly you want. Please give some better example Commented Jul 17, 2011 at 18:58
  • You are already accessing uname inside wrapperfunc directly and passing the remaining args to mainfunc. Please explain. Commented Jul 17, 2011 at 19:10
  • I've made an edit. Please have a look. Sorry for the lack of clarity in my question. Commented Jul 17, 2011 at 19:30

3 Answers 3

5

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)`
Sign up to request clarification or add additional context in comments.

Comments

1

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)

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.