在局部变量名与函数参数名相同时将关键字参数传递给函数
有没有更简洁的写法呢?
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
只是变量的名字,很容易看出正确的顺序。然而不幸的是,我程序中的变量名字比较复杂,没有明显的自然顺序。所以我真的很想用关键字来传递它们,以避免出错。
3 个回答
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)
4
locals()
可以让你看到当前的局部变量,所以你可以这样做:
def somewhere():
x = 3 # its a local
f(**locals()) # same as f(x=3)
不过你肯定能明白,这种做法是非常脆弱的。
7
你可以这样做:
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()
建议。