2011-05-02 112 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

相關問題