0

この python コードを実行すると、以下の出力が生成されます。

class A(object):
    a = 0
    n = {}

    def inc(self):
        self.a += 1

    def add(self, key, obj):
        self.n[key] = obj

    def printn(self):
        print self.a
        print self.n


b = A()
c = A()

b.add("asf", "----")
c.add("asdf", "====")

b.inc()
c.inc()

b.printn()
c.printn()

出力:

1
{'asf': '----', 'asdf': '===='}
1
{'asf': '----', 'asdf': '===='}
4

2 に答える 2

5

n問題は辞書であることとは何の関係もありません。インスタンス属性でnはなくクラス属性です。つまり、クラスのすべてのインスタンスが単一の値を共有します。

解決策は、単純にインスタンス変数に変換すること__init__です。つまり、クラス定義内ではなく、メソッド (通常はメソッド) 内で割り当てます。

class A(object):
    def __init__(self):
        self.n = {}

で同じことが起こらない理由を尋ねるかもしれませんa。そうですね。_ aと同じように、単一の shared を作成していnます。

ただし、その共有aでそれを変更するメソッドを呼び出していません (実際、変更できないためint、それはできません。それを変更するメソッドはありません)。ではnself.n[key] = objectメソッド呼び出しのようには見えないかもしれませんが (実際にはです)、ここで重要な in-placeself.n.__setitem__(key, object)の値を変更していることは明らかです。n

に新しい値を割り当てているだけですself.a。これにより、同じ名前のクラス属性をシャドウする新しいインスタンス属性が作成されます。これは紛らわしいですが、希望どおりに機能します。n新しい値を作成してに割り当てるだけで、必要に応じて同じ動作を得ることができますself.n

def add(self, key, obj):
    new_n = copy.copy(n)
    new_n[key] = obj
    self.n = new_n
于 2013-08-30T23:23:20.983 に答える
0
n = {}

これは、他の言語の場合とは異なります。他の言語では、これは常に空の dict で初期化されるインスタンス属性を宣言すると予想される場合があります。Python では、class 属性を作成します。すべてのインスタンスは同じ を共有しますn

これを修正するには、コンストラクターを作成し、属性を on に設定しますself

def __init__(self):
    self.a = 0
    self.n = {}
于 2013-08-30T23:23:24.653 に答える