Ferguzz
Ferguzz

Reputation: 6087

python named arguments auto-naming

So if I have a function which takes loads of named arguments:

def foo(a = 1, b = 2, c = 3, d = 4, e = 5) # etc...
    pass

and I'm calling it with all the arguments having exactly the same names as in the definition:

a = 0
b = 0
c = 0
d = 0
e = 0

is there a way to avoid doing this?

foo(e = e, b = b, d = d, a = a, c = c)

and just do this:

foo(e, b, d, a, c)

?

I guess I can do this:

foo(a, b, c, d, e)

but what if the arguments have complicated names and I can't remember the order of them by heart?

Upvotes: 0

Views: 719

Answers (5)

Russell Borogove
Russell Borogove

Reputation: 19037

Calling a 5-argument function with a completely different set of arguments each time is pretty rare. If, in practice, you're using the same a, c, and e args most of the time and calling with different b and d args (for example), you can create a class to help you with this:

class FooWrapper(object):
    def __init__( self, commonA, commonC, commonE ):
        self.a = commonA
        self.c = commonC
        self.e = commonE

    def invokeFoo( self, _b, _d ):
        foo( a=self.a, b = _b, c = self.c, d = _d, e = self.e )

w = FooWrapper( 1, 2, 3 )
w.invokeFoo( 4, 5 )          # calls foo( 1, 4, 2, 5, 3 )
w.invokeFoo( 6, 7 )          # calls foo( 1, 6, 2, 7, 3 )

Upvotes: 0

Abhijit
Abhijit

Reputation: 63737

If changing the function is not an option for you but you have the liberty to change the methodology in which you are assigning value to the parameters passed, here is a example code that might be helpful to you. This used orderdict to preserv the

Given

>>> def foo(a = 1, b = 2, c = 3, d = 4, e = 5):
    print "a={0},b={1},c={2},d={3},e={4}".format(a,b,c,d,e)

the you can do

>>> var=dict()
>>> var['c']=12
>>> var['a']=10
>>> var['b']=11
>>> var['e']=14
>>> foo(**var)
a=10,b=11,c=12,d=4,e=14

Note, this answer is similar to what was proposed by @thg435 but you are

  1. Not using inspect to hack the arguments a function expects.
  2. Not looking through the local/global dictionary.
  3. Supports missing arguments which defaults to what is the default argument.
  4. And off-course you do not have to remember the order.
  5. And you don;t even have to pass the variables as parameters. Just pass the dictionary.

Upvotes: 3

Matt Fenwick
Matt Fenwick

Reputation: 49095

Python's argument passing mechanisms are extremely flexible. If they're not flexible enough, this seems like a design smell to me ...

  • possible smell: too many arguments to a function. Solutions: split into multiple functions, pass some args together in a dictionary or object.

  • possible smell: bad variable names. Solution: give variables more descriptive names.

Or just bite the bullet, figure out the correct order, and keep it simple.

Upvotes: 3

sega_sai
sega_sai

Reputation: 8538

You can do the following:

def func(a=1, b=2, c=3, **kw):
    print a,b,c

a = 11
b = 22
c = 33

func(**locals())

Upvotes: 0

georg
georg

Reputation: 214959

Well, you could do something like:

def foo(a, b, c, d):
    print a, b, c, d


d = 4
b = 2
c = 3
a = 1

import inspect
foo(*[locals().get(arg, None) for arg in inspect.getargspec(foo).args])

but I'm not sure I can recommend this... In practice I'd use a dictionary of arguments:

foo_params = {
    'd' : 4,
    'b' : 2,
    'c' : 3,
    'a' : 1
}

foo(**foo_params)

of write a wrapper for foo which uses less arguments.

Upvotes: 5

Related Questions