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?
a=a
, for the other ones use b=0
- Sven Marnach 2012-04-05 16:44
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.
**kwargs
- Sven Marnach 2012-04-05 16:51
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.
foo
Matt Fenwick 2012-04-05 16:56
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
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())
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 )
foo(e=0, b=0, d=0, a=0, c=0)
- Sven Marnach 2012-04-05 16:39