2009-05-26 28 views
3

我做科學編程,經常想要顯示用戶提示和變量對,讓他們編輯變量,然後用新變量進行計算。我經常這樣做,我寫了一個wxPython類來將這些代碼移出主程序。用變量類型(string,float,int),提示符和變量的當前值爲每個變量設置一個列表。然後將所有這些列表放在一個大列表中,我的實用程序創建一個整齊的wxPython面板,其中包含提示和可編輯的當前值。如何向Python中的函數傳遞大量變量?

當我開始時,我只有幾個變量,所以我會寫出每個變量。

s='this is a string'; i=1; f=3.14 
my_list=[ ['s','your string here',s], ['i','your int here',i], ['f','your float here'],] 
input_panel = Input(my_list) 

# the rest of the window is created, the input_panel is added to the window, the user is 
# allowed to make choices, and control returns when the user hits the calculate button 

s,i,f = input_panel.results()  # the .results() function returns the values in a list 

現在我想使用這個例程的很多變量(10-30),這種方法是打破。我可以使用list.append()語句在多行上創建輸入列表。但是,當代碼從函數返回時,我會得到這個需要解壓縮到正確變量中的巨大列表。這很難管理,看起來很容易讓輸入列表和輸出列表不同步。更糟的是,它看起來很爛。

什麼是將大量變量傳遞給Python中的一個函數的最佳方式,以便可以對它們進行編輯,然後獲取變量以便我可以在程序的其餘部分使用它們?

如果我可以通過引用將變量傳遞給函數,那麼用戶可以改變它們,也可以不改變,並且一旦程序從函數返回,我會使用這些值。我只需要在多行中構建輸入列表,並且不會有任何輸入列表與輸出列表不同步的可能性。但是Python不允許這樣做。

我是否應該將大列表分解爲更小的列表,然後將它們合併爲大列表來傳入和退出函數?或者這只是添加更多的地方來犯錯誤?

回答

15

最簡單的事情就是創建一個類。該類不會處理變量列表,而會具有屬性。然後,您只需使用該類的單個實例。

+0

無法計算我在生活中所做的「搜索屬性」類的數量。 +1 – 2009-05-26 20:27:57

+0

絕對從一個類開始。然後,您可能會發現一些可以拆分爲多個類的數據,或可以移入該類的行爲。但是創建參數對象是第一步。 – 2009-05-26 20:58:37

0

如果你有這些情況的有限集合,你可以爲每個包裝函數編寫特定的包裝函數。每個包裝將完成構建和解包列表傳遞給內部函數的工作。

1

如果我可以通過引用傳遞變量到函數中,那麼用戶可以改變它們或不改變,並且一旦程序從函數返回,我會使用這些值。

可以得到多達「按引用傳遞」通過使dict(或句法方便Bunch,見http://code.activestate.com/recipes/52308/)相同的效果。

9

有兩個不錯的選擇,想到。

第一種方法是使用字典,收集所有的變量在同一個地方:

d = {} 
d['var1'] = [1,2,3] 
d['var2'] = 'asdf' 
foo(d) 

的第二種方法是使用一個類來捆綁所有的參數。這可能是簡單的東西如:

class Foo(object): 
    pass 
f = Foo() 
f.var1 = [1,2,3] 
f.var2 = 'asdf' 
foo(f) 

在這種情況下,我寧願類在字典中,僅僅是因爲你最終可以定義爲類,以使其使用更清晰或提供一些能夠處理方法的包裝和拆包工作。

2

對我來說,理想的解決方案是使用像這樣的類:

>>> class Vars(object): 
...  def __init__(self, **argd): 
...    self.__dict__.update(argd) 
... 
>>> x = Vars(x=1, y=2) 
>>> x.x 
1 
>>> x.y 
2 

您還可以構建一個字典,並將它傳遞這樣的:

>>> some_dict = {'x' : 1, 'y' : 2} 
>>> #the two stars below mean to pass the dict as keyword arguments 
>>> x = Vars(**some_dict) 
>>> x.x 
1 
>>> x.y 
2 

然後,您可以獲取數據或改變它,因爲它傳遞給一個函數時,需要的話:

>>> def foo(some_vars): 
...  some_vars.z = 3 #note that we're creating the member z 
... 
>>> foo(x) 
>>> x.z 
3 
0
  1. 我會建議使用字典 或類積累的所有細節 有關的變量
    • 提示文本
  2. 列表存儲在您希望他們能夠顯示
  3. 順序
  4. 然後使用良好的舊迭代準備輸入和收集輸出

這樣你只會是m一次又一次地對代碼的一小部分可管理部分進行修改。 當然,如果你喜歡與課程一起工作,你應該將所有這些封裝到一個類中。

"""Store all variables 
""" 
vars = {} 
"""Store the order of display 
""" 
order = [] 

"""Define a function that will store details and order of the variable definitions 
""" 
def makeVar(parent, order, name, value, prompt): 
    parent[name] = dict(zip(('value', 'prompt'), (value, prompt))) 
    order.append(name) 

"""Create your variable definitions in order 
""" 
makeVar(vars, order, 's', 'this is a string', 'your string here') 
makeVar(vars, order, 'i', 1, 'your int here') 
makeVar(vars, order, 'f', 3.14, 'your float here') 

"""Use a list comprehension to prepare your input 
""" 
my_list = [[name, vars[name]['prompt'], vars[name]['value']] for name in order] 
input_panel = Input(my_list) 

out_list = input_panel.results(); 
"""Collect your output 
""" 
for i in range(0, len(order)): 
    vars[order[i]]['value'] = out_list[i];