5

私は科学的プログラミングを行っており、ユーザーにプロンプ​​トと変数のペアを表示し、変数を編集させてから、新しい変数を使用して計算を実行させたいことがよくあります。私はこれを頻繁に行うので、wxPython クラスを作成して、このコードをメイン プログラムから移動しました。変数の型 (string、float、int)、プロンプト、および変数の現在の値を使用して、変数ごとにリストを設定します。次に、これらすべてのリストを 1 つの大きなリストに配置すると、私のユーティリティが適切にフォーマットされた 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 はこれを許可しません。

大きなリストを小さなリストに分割してから、関数に出入りするために大きなリストに結合する必要がありますか? それとも、エラーを起こす場所が増えるだけですか?

4

6 に答える 6

16

最も簡単なことは、クラスを作成することです。変数のリストを扱う代わりに、クラスには属性があります。次に、クラスの単一のインスタンスを使用するだけです。

于 2009-05-26T20:25:40.000 に答える
9

頭に浮かぶ2つのまともなオプションがあります。

1つ目は、辞書を使用してすべての変数を1か所に集めることです。

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

2つ目は、クラスを使用してすべての引数をバンドルすることです。これは、次のような単純なものである可能性があります。

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

この場合、ディクショナリよりもクラスを優先します。これは、クラスの定義を最終的に提供して、クラスの使用を明確にしたり、パックおよびアンパック作業の一部を処理するメソッドを提供したりできるためです。

于 2009-05-26T20:29:08.743 に答える
3

私にとって理想的な解決策は、次のようなクラスを使用することです。

>>> 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
于 2009-05-26T20:29:25.403 に答える
1

参照によって変数を関数に渡すことができれば、ユーザーは変数を変更するかどうかを指定でき、プログラムが関数から戻ったら値を使用します。

aを渡すことで「参照渡し」とほぼ同じ効果を得ることができますdict(または構文上の便宜のために、 http://code.activestate.com/recipes/52308/Bunchを参照してください)。

于 2009-05-26T20:27:47.607 に答える
0

これらのケースの有限セットがある場合は、それぞれに特定のラッパー関数を記述できます。各ラッパーは、内部関数に渡されるリストの作成と解凍の作業を行います。

于 2009-05-26T20:26:20.137 に答える
0
  1. 辞書またはクラスを使用して、変数に関するすべての詳細を蓄積することをお勧めします
    • 価値
    • プロンプト テキスト
  2. 表示したい順番を保存するリスト
  3. 次に、古き良き反復を使用して入力を準備し、出力を収集します

このようにして、コードの小さな管理可能なセクションを何度も変更するだけです。もちろん、クラスの操作に慣れている場合は、これらすべてをクラスにカプセル化する必要があります。

"""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];
于 2009-05-27T01:18:09.487 に答える