2016-04-14 7 views
-2

私はクラスとしてgeneralと呼ばれ、配列としてmsgs[]を属性として持っています。文字列であるmsgという属性もあります。私は3つのクラスgen0, gen1, gen2をインスタンス化し、各オブジェクトをarr (arr = [gen0, gen1, gen2])という配列に格納します。なぜこのコードは1つではなく3つの配列値を生成していますか? python 3.x

Iは、ID(配列arrインデックスidでオブジェクトを指すように)与え、snd(self, id, somemsg)というクラスgeneralのメソッドを定義して、アレイmsgs[]に文字列を追加somemsg。 たとえば、gen0.snd(1,"hello")gen1.msgs.append("hello")を実行します。

def snd(self, dst, msg): 
    listGens[dst].msgs.append(msg) 

Iは、上記で定義したようgeneralがクラスのインスタンスであり、以下の関数を定義しています。

def playGeneral(general): 
    for val in listGens: 
     if(val.id is general.id): 
      general.snd(general.id, " ") 
      continue 
     general.snd(val.id, general.oc) 

playGeneral(gen0)を呼び出すとき、somemsg変数が「A」であることを起こるれ、即ちgen0.msggenX.msg = "A"に設定されています。これを行うと、私たちは得る

playGeneral(listGens[0]) 
    for val in listGens: 
    print(val.msgs) 

[' ', 'A', 'A'] 
[' ', 'A', 'A'] 
[' ', 'A', 'A'] 

私はこれがなぜ起こっているのか理解できません。元になりmsgsクラス属性ではなく、インスタンス属性

class general: 
    def __init__(self, msgs=[]): 
     self.msgs = msgs 

class general: 
    msgs = [] 

か:あなたgeneralクラスは、次のように定義されています。それは

[' '] 
['A'] 
['A'] 
+4

答えは、少なくとも部分的に、あなたが提供しなかった 'general.snd'のコードに依存しませんか? –

+0

私は、逐語的に説明しましたが、私はコードを含めました。 – socrates

+0

関連するコードは、 'general'の' msgs'属性がどのように初期化されているかを示すものです。 – donkopotamus

答えて

2

サイキックデバッグを与えるべきですしたがって、クラスとすべてのインスタンス間で共有されますが、後者は0をデフォルトとして使用するすべてのインスタンスで単一のlistを共有します。両方の解決策は同じです。それぞれに独自のlistを使用します。

class general: 
    def __init__(self, msgs=()): 
     self.msgs = list(msgs) # Explicitly convert and shallow copy as list 

第三の可能性は、あなたがmsgs = []gen0 = general(msgs)gen1 = general(msgs)など、またはgen0 = gen1 = gen2 = general([])、またはlistgens = [general()] * 3などのような愚かな何かをしたということです、すべて同じ問題に沸きます:あなたは同じデータへの単一の参照を複数回保存しており、異なる値を持つ必要があります。

+0

ありがとうございます!私はそれをインスタンス属性にしていませんでした!私の頭を壁に1時間叩いた。ありがとう!! – socrates

+2

@socrates:どうぞよろしくお願いいたします。私の最初の精神的直感がうまくいくと、いつも幸せです。 :-) – ShadowRanger

+0

@ShadowRanger:あなたはまた神の水を飲むことができますか? – mhawke

関連する問題