我做科学编程,并且经常想要向用户显示提示和变量对,让他们编辑变量,然后用新变量进行计算。我经常这样做,我写了一个wxPython类来将这段代码移出主程序。您可以使用变量类型(字符串,浮点数,整数),提示符和变量的当前值为每个变量设置一个列表。然后将所有这些列表放在一个大的列表中,我的实用程序创建了一个整齐的wxPython面板,其中包含提示和可以编辑的当前值。
当我开始时,我只有一些变量,所以我会写出每个变量。
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不允许这样做。
我是否应该将大型列表拆分为较小的列表,然后将这些列表组合成大型列表以进入和退出函数?或者这只会添加更多地方来制作错误?
答案 0 :(得分:15)
最简单的方法是创建一个类。该类将具有属性,而不是处理变量列表。然后你只需使用该类的一个实例。
答案 1 :(得分: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 :(得分: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
答案 3 :(得分:1)
如果我可以通过引用将变量传递给函数,那么用户可以更改它们,并且一旦程序从函数返回,我将使用这些值。
通过传递dict
(或语法方便Bunch
,您可以获得与“通过引用传递”相同的效果,请参阅http://code.activestate.com/recipes/52308/)。
答案 4 :(得分:0)
如果你有一组有限的这些案例,你可以为每个案例编写特定的包装函数。每个包装器都可以完成构建和解包列表的工作,并将其传递给内部函数。
答案 5 :(得分:0)
通过这种方式,您只需要修改代码的一小部分可管理部分。 当然,如果你习惯使用类,你应该将所有这些封装到一个类中。
"""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];