2016-08-16 7 views
2

私は、run_cと呼ばれるクラスを持っています。これは、キネマティックシミュレーションの実行を初期化して実行するために使用されています。 run_c.__init__()が実行される前に、xのような属性のデフォルト値をrun_cに割り当てます。 __init__()は、ユーザー入力値を抽出して辞書に集約し、対応する属性に対応する属性を割り当てます(run_c)。たとえば...オブジェクトは以前のループ反復からの情報を保持します

import vars.Defaults as dft 
class run_c: 

    ... 
    dt  = dft.dt 
    x  = dft.x0 
    states = [ [], [], [], [] ] 
    ... 

    def __init__(self, input): 
     for key in input.keys(): 
     if hasattr(self, key): setattr(self, key, input[key]) 
     ... 
     self.execute() 

run_c.statesは、彼らがタイムステップで変化するようrun_c属性の値を記録するために使用されているリストのリストです。後でrun_c.execute()の範囲内で、states[1]xの値を格納し、タイムステップを増やしてdtとし、速度とタイムステップを使用してxを更新します。それはかなりシンプルなものですよね?...

ここで問題はどこから始まりますか。 run_cのインスタンスが初めて作成され、初期化され、実行されると、完全に実行されます。しかし、私はこのシミュレーションを、JSONファイルから読み取ったリストに基づいて複数の実行を作成、初期化、実行することで運用しています。そのため、ドライバモジュールで...

from Run import run_c 
def main(): 
    ... 
    for runEntry in runList: 
     currRun = run_c(runEntry) 
     ... 
    ... 

は何が起こるかというとrun_c.statesに保存されたすべての値は、ループの各反復の後に拭かれませんということです。私はの新しいインスタンスが私がループを実行するたびに新しい情報で__init__()を実行するように作成されていると考えました。 xの古い値などのデータ値が、各ループの終了後も保持されるのはなぜですか?

更新:statesの値を__init__()の空のリストに戻すコード行を追加すると、問題はなくなります。しかし、これは私がやりたいことに必要なステップではありません...それは必要ですか?

+0

「状態」に*新しい空のリストをどれくらい頻繁に作成していますか?一度:クラスを定義している間。リストオブジェクトは新しいインスタンスごとにリセットされません。 – deceze

+0

'states'だけが割り当てられ、使用されていないリストはありますか?私が 'self.states'と言えば、それは完全に別個の存在ですか?それとも、クラス変数よりもグローバル変数に似ていますか? –

答えて

7

dtx、及びstatesクラス変数ないインスタンス変数として定義されます。あなたが作るクラスのすべてのインスタンスがそれらを共有します。既存の回答に加えて

class run_c: 

    def __init__(self, input): 
     ... 
     self.dt  = dft.dt 
     self.x  = dft.x0 
     self.states = [ [], [], [], [] ] 
     ... 

     for key in input.keys(): 
     if hasattr(self, key): setattr(self, key, input[key]) 
     ... 
     self.execute() 
0

:あなたは新しいインスタンスを生成するたびに初期化するためにそれらを必要とする場合、それは__init__()が何のためにあるのかを正確だあなたは__new__方法でこれらの変数を初期化することができます。あなたが__new__メソッドを削除した場合

class A: 
    val = 1 

    def __new__(cls, v): 
     t = super().__new__(cls) 
     t.val = v 
     return t 

    def __init__(self, v): 
     val = v 

a, b = A(1), A(2) 

print(a.val, b.val) 

、output'dは1 1とそうでない1 2こと。

+0

@BruceDavidWilner、いいえ、誰も「スーパー」はそれを気にしないので、クラス階層に陥ることはありません。いいえ、これらの「魔法」メソッドのセマンティクスはあいまいではありません。あなたはそれらを一度書くだけです。クラスを使用すると、それらはまったく表示されません。この答えは、変数の定義を '__init__'にどのように移動してOPの目標を達成するのかを示しています。 – ForceBru

関連する問題