2017-09-05 39 views
0

我有一個OrderedDict的值,我想成爲功能,但遇到意外的行爲。初始化:Python的字典/ OrderedDict:賦值函數,而不立即執行它

from collections import OrderedDict 

options_dict=OrderedDict(["A",call_func_A(arg1,arg2)], 
         ["B",call_func_B(arg1,arg3)], 
         ["C",call_func_C(arg1,arg4)] 

# Select options 
options=["A","C"] 

# Execute 
result={} 
for opt in options: 
    result[opt]=options_dict[opt] 

# Return result (or whatever) 
print result 

功能call_func_A,call_func_B和call_func_C轉出時options_dict被宣告執行,而不是在for循環在選項之後。

我希望函數調用等到for循環。

發生了什麼事?

+1

'call_func_A'是函數,'call_func_A(arg1,arg2)'正在調用函數 –

回答

0

首先,您是錯誤地聲明OrderedDict。構造函數需要一個元組列表。相反,你給它多個列表。做到這一點,像這樣:

options_dict=OrderedDict([("A",call_func_A(arg1, arg2)), 
          ("B",call_func_B(arg1, arg3)), 
          ("C",call_func_C(arg1, arg4))]) 

其次,當你聲明options_dict,你不及格的功能作爲字典的值,而是其結果:

options_dict=OrderedDict(["A",call_func_A(arg1,arg2)], 
         ["B",call_func_B(arg1,arg3)], 
         ["C",call_func_C(arg1,arg4)]) 

您是美其名曰通過執行call_func_A(arg1, arg2)。避免的一個比較簡單的方法是通過省略ARGS:

options_dict=OrderedDict([("A",call_func_A), 
         ("B",call_func_B), 
         ("C",call_func_C)]) 

您可以將ARGS存儲在第二OrderedDict:

args_dict=OrderedDict([("A",[arg1, arg2]), 
         ("B",[arg3, arg4]), 
         ("C",[arg5, arg6])]) 

然後打電話給他們:

result={} 
for opt in options: 
    result[opt]=options_dict[opt](*args_dict[opt]) 
3

在創建字典之前調用函數。你打了電話。

但是,您可以通過另一個函數嵌套在它推遲函數調用稍後調用:

options_dict = OrderedDict([("A", lambda: call_func_A(arg1,arg2)), 
          ("B", lambda: call_func_B(arg1,arg3)), 
          ("C", lambda: call_func_C(arg1,arg4))]) 

# Select options 
options = ["A", "C"] 

# Execute 
result = {} 
for opt in options: 
    result[opt] = options_dict[opt]() # <- call 

同樣的效果可以用functools.partial來實現,一個額外的import語句來執行。

另一方面,由於你的函數參數大概是不變量,我不認爲在什麼時候調用是很重要的。你最好保留你在dict創建時調用函數的初始方法。

+0

推遲的原因是相對昂貴,我只想調用一個子集(按順序)。也許有一個更簡單的方法。 – jtlz2

+0

目前,我得到TypeError:預計最多1個參數,得到3 – jtlz2

+0

@ jtlz2代碼摩西Koledoye提供的是正確的。問題在於你如何創建OrderedDict。查看我的答案的第一部分,瞭解正確的方法。 – stybl