2016-09-30 18 views
4

Pythonでクラスのインスタンスを初期化するときに、クラス属性を使用できないのはなぜかと思います。ここでは一例です:クラスのインスタンスが表示される前にPythonのクラスとインスタンスの初期化

class TestClass: 
... shared_list = ['a', 'b', 'c'] 
... def __init__(self): 
...  self.length = len(shared_list) 

>>> TestClass.shared_list 
['a', 'b', 'c'] 

ので、リストが存在するが、

>>> tc = TestClass() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 4, in __init__ 
NameError: global name 'shared_list' is not defined 

私は、単純な何かが足りないのですか?

UPD:皆様のおかげで、迅速な対応に感謝します。私は私の混乱を解消しました。クラスはPythonでスコープを定義していません。

+7

スコープ付き 'shared_list'を使用する場合は、' self.shared_list'または 'TestClass.shared_list'が必要です。 – AChampion

+0

@AChampion Thanks、TestClass.shared_listで修正しました。 C + +から来て、私はそれが混乱していることがわかります。*クラス内では、クラスへの明示的な参照が必要です。私は、インスタンス内に属性が見つからない場合、それがクラス内で検索され、グローバルに検索されるのではないと考えました。 – LazyCat

+1

残念ながら、上記のスコープルールを参照してください。 – AChampion

答えて

3

class定義は、そのメソッドのための新しいスコープ、ローカル変数のためだけの名前空間を作成しません。これはClass Definition Syntaxにある程度の文書化されている:クラス定義が入っている

は、新しい名前空間が作成され、 はローカルスコープとして使用する - このように、ローカル変数へのすべての割り当ては、この新しい名前空間に を行きます。特に、関数定義はここで新しい関数の名前をバインドします。

クラス定義が正常終了(最後まで)の場合、クラスオブジェクト が作成されます。これは、基本的にクラス定義によって作成された 名前空間の内容を包むラッパーです。

そのため、クラス属性をTestClass.shared_listまたはself.shared_listというメソッドで参照する必要があります。

+0

ありがとう、それはまさに私の混乱の原因でした。 – LazyCat

1

変数shared_listの "環境"を指定しない場合、ここではselfまたはTestClassです。pythonはそれがグローバル変数であると判断します。

self.shared_listまたはTestClass.shared_listを参照してください。

2

この問題は__init__関数で発生し、TestClassをインスタンス化するときに呼び出されます。

__init__関数は変数shared_listを使用しますが、実際にはこの変数はインスタンスまたは基本クラス自体に関連付けられている場合にのみ使用できます。共有変数を変更したい場合は、クラス名とそれを呼び出す必要があります。

def __init__(self): 
    self.length = len(TestClass.shared_list) 

あなただけのそのインスタンスの変数を変更したい場合は、インスタンス変数として宣言する必要があります。

def __init__(self): 
    self.not_shared_list = ['a', 'b', 'c'] 
    self.length = len(self.not_shared_list) 
+1

注: 'self.share_list'は' TestClass.shared_list'を参照し、 'self.share_list'の変更はクラス変数を変更します。 – AChampion

+0

@AChampionありがとう - それに応じて変更されました。 – brianpck

+0

ありがとうございます - 私はあなたの答えをupvotedしましたが、私は混乱のソースに正確に対処するため、別のものを受け入れました。クラスはPythonでスコープを作成しません。 – LazyCat