2011-05-02 119 views
6

是否有更简洁的方式来编写它?当局部变量名称与函数参数名称相同时,将关键字参数传递给函数

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

背景:我有太多的争论

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

功能我在我的节目,我有一个被命名为函数的参数完全相同局部变量。

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

我想用关键字参数调用函数。由于变量名称相同,这就是调用的外观。

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

当然,我可以这样

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

abcde使用位置,而不是关键字的变量只是名字传递aruguments在这个例子中,它很容易看到正确的顺序。但不幸的是,我的程序中的变量名称更复杂,并且没有容易辨别的自然顺序。所以我真的很喜欢通过关键字来传递它们以避免任何错误。

回答

5

你可以做类似如下:

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},这样你就可以打电话给你的功能是这样的:

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

这使您能够准确地指定要哪个变量的能力使用。另一种不使用globals()的方法是使用eval(),但它可能会使得lambda可能不安全。

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

如果您希望在通过locals()作为参数,而不是在lambda使用globals()您可以使用以下方法:

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

感谢senderlelocals()建议。

+0

小问题:不应该是'本地人? – senderle 2011-05-02 19:22:02

+0

'lambda'有它自己的作用域,所以如果它在lambda内被使用(但它们将在'globals()')中,那么它的包含作用域的局部变量不在'locals()'中。 – 2011-05-02 19:24:22

+0

Wunderbar!这正是我所期待的。谢谢!我同意@senderle,我可以使用'locals()'而不是'globals()'。 – 2011-05-02 19:24:43

1

为什么你不能在这里使用**千瓦?

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

我同意这将是自然的选择。但是,foo()是在外部模块中定义的,我无法控制函数的定义。 – 2011-05-02 18:43:32

+0

另一种方法是将bar()定义为foo()的包装并传递参数,但我想知道是否有更简单的方法。 – 2011-05-02 18:44:39

1

locals()给你的局部变量,所以你可以做

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

,但你肯定可以看到非常脆弱,这是。

+0

我也在想当地人。但它似乎不是解决这个问题的“优雅”方式。如果全部失败,可能是我应该坚持蛮力!:) – 2011-05-02 19:05:09

相关问题