6

私は Python クラスをいじっていて、次の例にたどり着きました。この例では、静的クラス変数のように見える 2 つの変数が変更されると異なる動作をします。

何が起きてる?私の最初の本能は、参照で何かトリッキーなことが起こっているということです。

class Foo:
    a = []
    n = 0
    def bar(self):
            self.a.append('foo')
            self.n += 1

x = Foo()
print x.a, x.n    ([] 0)
x.bar()
print x.a, x.n    (['foo', 1])
y = Foo()
print y.a, y.n    (['foo', 0])
y.bar()
print y.a, y.n    (['foo', 'foo'], 1)
4

1 に答える 1

5

あなたは正しいです -実際にアクセスFoo.aする場合は、 のすべてのインスタンス間で共有されます。ただし、更新すると、実際にはそのシャドウにインスタンスレベルの変数が作成されます。self.aFoo.aFooself.n+=selfFoo.n

>>> import dis
>>> dis.dis(Foo.bar)
  5           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (a)
              6 LOAD_ATTR                1 (append)
              9 LOAD_CONST               1 ('foo')
             12 CALL_FUNCTION            1
             15 POP_TOP             

  6          16 LOAD_FAST                0 (self)
             19 DUP_TOP             
             20 LOAD_ATTR                2 (n)
             23 LOAD_CONST               2 (1)
             26 INPLACE_ADD         
             27 ROT_TWO             
             28 STORE_ATTR               2 (n)
             31 LOAD_CONST               0 (None)
             34 RETURN_VALUE    

言い換えればself.a.append('some value')、インタープリターが実行するとa、名前を介してメモリからフェッチし、ポイントするFooリストを変更します。Foo.a

一方、self.n += 1インタープリターを実行すると、次のようになります。

  • nから取得しますFoo( で見つからないため)nself
  • 新しい価値を創造しますn + 1
  • の属性nに新しい値を格納します。self
于 2013-05-29T04:48:41.667 に答える