web-dev-qa-db-ja.com

クラス変数はPythonのすべてのインスタンスで共有されていますか?

1週間前にpython=でコーディングを開始しました。すぐにoops、classes、objectsを使用してコーディングを始めたのは私の間違いです。C++の熟練度が役立つと思いました..。次のコード

class A:
     var=0
     list=[]
     def __init__(self):
            pass

ここで驚いたことに、varとlistはグローバル変数であり、すべてのインスタンス間で共有されているようです。すべてのインスタンス間で異なると私が思ったのは....理解するのに半日かかりましたthat ....変数はクラスオブジェクトからのみアクセスできるが、すべてのインスタンス間で共有されるということは、少しでも意味がありません。……奇妙なことに、その背後に理由がありますか??? ??

26

varは、instance.varまたはself.varでアクセスする限り、絶対に共有しないでください。ただし、リストでは、クラスが評価されたときにステートメントが行うことは、1つのリストインスタンスが作成され、クラスdictにバインドされるため、すべてのインスタンスが同じリストを持つことになります。 instance.list = somethingelse respを設定したとき。 self.list = somethingelse、インスタンスレベルの値を取得する必要があります。

時間の例:

>>> class A():
...     var = 0
...     list = []
...
>>> a = A()
>>> b = A()
>>> a.var
0
>>> a.list
[]
>>> b.var
0
>>> b.list
[]
>>> a.var = 1
>>> b.var
0
>>> a.list.append('hello')
>>> b.list
['hello']
>>> b.list = ['newlist']
>>> a.list
['hello']
>>> b.list
['newlist']
28
mensi

これらは基本的にJavaの静的変数に似ています。

// Example equivalent Java
class A {
    static int var = 0;
    static String[] list;
}

これは意図された動作です。クラス変数はクラスの場合です。

通常のインスタンス変数の場合は、コンストラクターで宣言します。

class A:
    def __init__(self):
        self.var = 0
        self.list = []

Pythonの静的クラス変数 を確認することをお勧めします。

15
Brendan Long

その理由は、Python classが他のように実行される実行可能ステートメントであるためです。クラス定義の本体は、クラスが定義されるときに一度実行されます。ラインvar = []の場合は、1回だけ実行されるため、その行の結果として作成できるリストは1つだけです。

5
BrenBarn

この動作はvarでは見られず、listでのみ見られることに注意してください。

>>> class A:
...     var = 0
...     list = []
... 
>>> a1 = A()
>>> a2 = A()
>>> a1.var = 3
>>> a2.var
0
2
Simeon Visser