2009-05-26 3 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

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

+0

私が自分の人生で行った「検索プロパティ」クラスの数をカウントできません。 +1 –

+0

間違いなく、クラスから始まります。次に、複数のクラスに分割できるデータや、クラスに移動できるビヘイビアを見つけることができます。しかし、引数オブジェクトの作成が最初のステップです。 –

+0

科学的ソフトウェアを運営する会社で働く人として、私はこれが正しいアプローチだとも考えています。変数全体を渡すことによって、あなたは基本的に問題のドメインのモデリングをあきらめています。代わりに、オブジェクトのコレクションとしてより論理的な意味で問題を具体化するクラス階層を構築することができます。 10-30の可変関数呼び出しは、学術の科学的背景から来るアマチュアプログラマーの典型的な兆候です。 –

0

これらのケースが有限であれば、それぞれのラッパー関数を記述することができます。それぞれのラッパーは、内部関数に渡されるリストの構築とアンパックの作業を行います。

1

変数を関数に渡すことができれば、ユーザーは変数を変更することができますが、関数から返された値を使用します。

あなたがはるか(http://code.activestate.com/recipes/52308/を参照するか、構文便宜上Bunchdictを通過させることによって、「参照渡し」と同様の効果を得ることができます。

9

2つの選択肢があります。

最初は一つの場所にあるすべての変数を収集するために辞書を使用することです:

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. あなたがそれらを表示したい順序を保存するためのリスト
    • あなたの変数に関する値
    • を蓄積するために辞書 またはクラスを使用することをお勧めします
    • 次に入力を用意して出力

あなたが唯一メートルになります。この道を収集するために、古き良き反復を使用コードの小さな管理可能なセクションを時代遅れにしています。 クラスで快適に作業する場合は、もちろんこれをすべてクラスにカプセル化する必要があります。

"""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]; 
+1

あなたのコメント方法は非標準ですので、pep-8をお読みください。 http://www.python.org/dev/peps/pep-0008/ – monkut

関連する問題