クラス変数を設定するには、完全なクラス名を使用する必要があります。cls
indouble_x
とtripple_x
はサブクラス (それぞれObjectOne
と) を参照し、これらのサブクラスに属性を設定すると、クラス変数は変更されず、新しい変数ObjectTwo
が格納されます。基本クラスの変数は、直接アクセスすることによってのみ変更できます。BaseObject.x
コードを使用すると、次のようになります。
>>> obj_1 = ObjectOne()
cls.initialized = False
>>> obj_1.double_x()
2
>>> obj_2 = ObjectTwo()
cls.initialized = False
>>> obj_2.triple_x()
3
>>> BaseObject.x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'BaseObject' has no attribute 'x'
>>> BaseObject.initialized, ObjectOne.initialized, ObjectOne.x, ObjectTwo.initialized, ObjectTwo.x
(False, True, 2, True, 3)
何が起こったかというと、作成したインスタンスに応じて in_initialize()
がor に設定され、各サブクラスは変数cls
andの独自のコピーを取得しました。ObjectOne
ObjectTwo
initialized
x
(サブクラスではなく、BaseObject._initialize()
確実に初期化するため)を使用すると、次のようになります。BaseObject
>>> obj_1 = ObjectOne()
cls.initialized = False
>>> obj_1.double_x()
2
>>> obj_2 = ObjectTwo()
cls.initialized = True
>>> obj_2.triple_x()
3
>>> BaseObject.x, ObjectOne.x, ObjectTwo.x
(1, 2, 3)
>>> BaseObject.initialized
True
>>> 'x' in ObjectOne.__dict__
True
>>> 'initialized' in ObjectOne.__dict__
False
>>> 'initialized' in ObjectTwo.__dict__
False
そのため、設定するターゲットと の初期値として_initialize()
使用されますが、独自のサブクラスを使用して の新しい値を設定し、を介してその値を共有していません。BaseObject
initialized
x
double_x
triple_x
x
BaseObject
特定の基本クラスにクラス変数を設定するために必要な唯一のオプションは、すべてのクラス メソッドで直接参照することです。
class BaseObject(object):
initialized = False
def __init__(self):
BaseObject._initialize()
@classmethod
def _initialize(cls):
print "cls.initialized = "+str(cls.initialized)
if not cls.initialized:
cls.x = 1
cls.initialized = True
class ObjectOne(BaseObject):
@classmethod
def double_x(cls):
BaseObject.x = BaseObject.x * 2
print cls.x
class ObjectTwo(BaseObject):
@classmethod
def triple_x(cls):
BaseObject.x = BaseObject.x * 3
print cls.x
これは次のようになります:
>>> obj_1 = ObjectOne()
cls.initialized = False
>>> obj_1.double_x()
2
>>> obj_2 = ObjectTwo()
cls.initialized = True
>>> obj_2.triple_x()
6
それがサブクラスであり、サブクラスではないBaseObject._initialize()
ことを確認するために呼び出したことに注意してください。次に、およびメソッドを設定するときに、 を直接参照して、変数が基本クラスに直接設定されるようにします。上記の例の値を読み取るときは、ローカルに設定されていない場合、クラス MRO を使用して基本クラスを検索します。cls
BasObject
x
double_x
triple_x
BaseObject
x
cls
x