开发者

Passing keyword arguments to a function when local variable names are same as function parameter names

Is there a more succint way to write this?

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

Background: I have a function with too many arguments

f(a, b, c, d, e):
    pass

I my program I have local variables that are named exactly same as the function parameters.

a, b, c, d, e = range(5)

I would like to call the function with keyword arguments. Since the variables are named the same, this is how the call would look.

g = f(a=a, b=b, c开发者_StackOverflow=c, d=d, e=e) # this can get very long

Of course, I can pass the aruguments using position instead of keywords like this

g = f(a, b, c, d, e) 

But a, b, c, d, e are just the names of variables in this example and it is easy to see the correct order. However unfortunately the variables in my program are named more complicatedly and there is no easily discernible natural order. So I really like to pass them by keyword to avoid any mistakes.


You could do something like the following:

a, b, c, d, e = range(5)
arg_dict = lambda l: dict((k, globals()[k]) for k in l.split(', '))

arg_dict('a, b, c, d, e') => {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3}, so you can call your function like this:

f(**arg_dict('a, b, c, d, e'))

This gives you the ability to specify exactly which variables you want to use. An alternative method for this that does not use globals() would be to use eval(), but it could make the use of the lambda potentially unsafe.

arg_dict = lambda l: dict(zip(l.split(', '), eval(l)))

If you would prefer to pass locals() in as an argument instead of using globals() in the lambda you can use the following:

arg_dict = lambda l, d=locals(): dict((k, d[k]) for k in l.split(', '))
f(**arg_dict('a, b, c, d, e'))

Thanks to senderle for the locals() suggestions.


locals() gives your local variables, so you could do

def somewhere():
  x = 3 # its a local
  f(**locals()) # same as f(x=3)

but you can surely see how very fragile this is.


Why can't you use **kw here?

def foo(**kw):
    for k,v in kw.items():
       print k,v


foo(a=2)
foo(a=3, b=4)
foo(nonsene=True, blather=False)
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜