13

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

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) 

但是a, b, c, d,e只是本例中变量的名称,很容易看出正确的顺序。然而不幸的是,我的程序中的变量命名更复杂,没有容易辨别的自然顺序。所以我真的很喜欢按关键字传递它们以避免任何错误。

4

3 回答 3

6

您可以执行以下操作:

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()作为参数传入而不是globals()在 lambda 中使用,则可以使用以下内容:

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

感谢senderlelocals()建议。

于 2011-05-02T19:16:29.137 回答
3

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

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

但你肯定可以看到这是多么脆弱。

于 2011-05-02T18:59:33.933 回答
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)
于 2011-05-02T18:40:46.290 回答