2009-05-26 73 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];