当局部变量名称与函数参数名称相同时,将关键字参数传递给函数

时间:2011-05-02 18:36:53

标签: python function-calls keyword-argument

有没有更简洁的方式来写这个?

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只是此示例中变量的名称,很容易看到正确订购。然而不幸的是,我的程序中的变量被命名为更复杂,并且没有容易辨别的自然顺序。所以我真的希望通过关键字传递它们以避免任何错误。

3 个答案:

答案 0 :(得分: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'))

感谢senderle提出的locals()建议。

答案 1 :(得分:2)

locals()提供您的本地变量,因此您可以执行

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

但你肯定能看出这是多么脆弱。

答案 2 :(得分:1)

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

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)