2012-02-08 9 views
2

Pythonは、クラス属性、インスタンス属性、およびプロパティをサポートしています。 MyClassのがどのように実装されるかを認識していないユーザー、A、Bへ属性やプロパティを初期化するにはどうしたらいいですか?

from time import ctime, sleep 

class MyClass(object): 
    A = ctime()   # class attribute 
    def __init__(self): 
     self.B = ctime() # instance attribute 
     self._C = None 

    @property 
    def C(self):   # property 
     if self._C is None: 
      self._C = ctime() 
     return self._C 
    @C.setter 
    def C(self, c): 
     self._C 

、およびCは同様の挙動を示す:

sleep(2) 
myObject = MyClass() 
sleep(2) 
print myObject.A   # prints time module was initialized 
print myObject.B   # prints time instance was created, 2 sec later 
print myObject.C   # prints time this line was called, 2 sec later 
myObject.A = 'foo'  # myObject.A is now an instance attribute 
myObject.B = 'foo'  # myObject.B is still an instance attribute 
myObject.C = 'foo'  # myObject.C is still an (instance) property 
print myObject.A   # prints 'foo' 
print myObject.B   # prints 'foo' 
print myObject.C   # prints 'foo' 

私がここに来たの答えから、私は次のことを理解:初めてmyObject.Aが印刷され、myObject.AmyObject.__Class__.AであることがMyClass.Aである。 2回目のmyObject.AmyObject.__Class__.Aではありません。ファイン。

上記の例では、ctime()は、A、B、およびCがどのように異なるかを説明するためだけに使用されていました。今、私たちが代わりに不変定数を使用している、と仮定します。

class MyClass(object): 
    A = 'bar'    # class attribute 
    def __init__(self): 
     self.B = 'meta'  # instance attribute 
     self._C = None 

    @property 
    def C(self):   # property 
     if self._C is None: 
      self._C = 'foobar' 
     return self._C 
    @C.setter 
    def C(self, c): 
     self._C = c 

myObject = MyClass() 

myObject.Aはまだクラス属性MyClass.Aで、myObject.Bは、インスタンス属性であるとmyObject.Cが財産である間。それらのすべては、私が欲しいものを正確に行います。彼らはデフォルト値を持っており、私は他の値を割り当てることができます。どののスタイルを使うべきですか?A、B、C?

+1

実際には、両方とも「機能しません」。彼らは両方とも同じことをしません。 'foo.A'は実際に**既存の' Foo.A'クラス変数の前にあるインスタンス変数を作成します**。 「どのスタイルを使うべきか」は、あなたの目的が何であるかに全面的に依存します。インスタンス変数やクラス変数が必要ですか?質問にあなたの目標を含めてください。 –

答えて

1

これは、初期化を実行したいときと、どのインスタンス化を望むかによって異なります。

  • クラスのすべてのインスタンス間で属性の1つのインスタンス(単一の値)を共有する場合は、class属性を使用します。
  • クラスの各インスタンスに属性の異なる値を設定する場合は、インスタンス属性を使用します。

脇に、コードサンプルにはプロパティではなく属性が含まれています。

あなたの質問に対する更新内容を理解できません。おそらく、元に戻って根本的な問題を説明する必要があります。

0

定数クラス属性を初期化するための好ましい方法は、クラス定義自体にあります。

質問のコードを見ると、インスタンスオブジェクトからクラス属性にアクセスする方法については混乱があるようです。

インスタンスオブジェクトでは、属性が内部ディクショナリに見つからない場合、クラス辞書内でルックアップが続行されるため、クラス属性に名前でアクセスできます。つまり、instance.Aが存在しない場合は、利用可能であればinstance.__class__.Aが返されます。

ただし、オブジェクトインスタンスで属性を作成すると、class属性がシャドウされます。つまり、instance.A = <value>は新しいインスタンス属性を作成し、次にinstance.Aにアクセスすると<value>が返されます。ただし、クラス属性は引き続きinstance.__class__.Aを使用して取得できます。

1

単純なプロパティまたは属性を作成するスタイルは2つあります。

これらは「スタイル」ではなく、実行されることは1つしかありません。

これらは異なる効果があります。

Pythonでは、classブロック内で宣言されたものがクラスに属するという論理的なルールに従います。したがって、Aはクラスの属性です(C++またはJavaまたはC#で宣言されたstaticにおおよそ類似しています)。 Bは、各インスタンスの属性で、__init__がインスタンスで実行されると自動的に生成されます。

あなたのアップデートについては、あなたが何を求めようとしているのか分かりません。 'A'ではなく、実際の名前を使用してユースケースを説明してください(つまり、なぜであれば何でもしたい)。

関連する問題