3

「クラス内の変数の定義」はクラス変数になるという次のPythonドキュメントを見ました。

プログラマーのメモ:クラス定義で定義された変数はクラス変数です。これらはすべてのインスタンスで共有されます。」

しかし、私がこのようなサンプルコードを書いたとき:

class CustomizedMethods(object):
    class_var1 = 'foo'
    class_var2 = 'bar'

cm1 = CustomizedMethods()
cm2 = CustomizedMethods()
print cm1.class_var1, cm1.class_var2 #'foo bar'
print cm2.class_var1, cm2.class_var2 #'foo bar'
cm2.class_var1, cm2.class_var2 = 'bar','for'
print cm1.class_var1, cm1.class_var2 #'foo bar' #here not changed as my expectation
print cm2.class_var1, cm2.class_var2 #'bar foo' #here has changed but they seemed to become instance variables.

私が試したものはPythonの公式ドキュメントとは異なるため、混乱しています。

4

5 に答える 5

4

インスタンスに属性を割り当てると、それが以前にクラスに存在していた場合でも、その属性はインスタンスに割り当てられます。最初は、class_var1そしてclass_var2確かにクラス属性です。ただし、これを行う場合cm1.class_var1 = "bar"、このクラス属性は変更されません。むしろ、と呼ばれる新しい属性を作成していますがclass_var1、これはインスタンスのインスタンス属性ですcm1

違いを示す別の例を次に示しますが、それでも把握するのは少し難しいかもしれません。

>>> class A(object):
...     var = []
>>> a = A()
>>> a.var is A.var
True
>>> a.var = []
>>> a.var is A.var
False

最初a.var is A.varはtrueです(つまり、それらは同じオブジェクトです):は、aという独自の属性を持っていないvarため、クラスを通過するアクセスを試みます。a独自のインスタンス属性を指定すると、クラスのインスタンス属性と同じではなくなります。

于 2012-09-11T04:27:14.997 に答える
1

インスタンスに属性を割り当てているので、そうです、それらはその時点でインスタンス変数になります。Pythonは、指定されたオブジェクトの属性を検索し、そこで属性が見つからない場合は、継承チェーン(クラス、クラスの親など)を検索します。したがって、インスタンスに割り当てる属性は、同じ名前のクラスの属性を「シャドウ」または「非表示」にします。

于 2012-09-11T04:27:53.513 に答える
0

変数を再割り当てするとcm2、クラス変数を「隠す」新しいインスタンス変数が作成されました。

>>> CustomizedMethods.class_var1 = 'one'
>>> CustomizedMethods.class_var2 = 'two'
>>> print cm1.class_var1, cm1.class_var2
one two
>>> print cm2.class_var1, cm2.class_var2
bar for
于 2012-09-11T04:26:43.980 に答える
0

文字列は不変であるため、クラス変数とインスタンス変数の違いはそれほど目立ちません。クラス定義内の不変変数の場合、注意すべき主な点は、メモリの使用量が少ないことです(つまり、CustomizedMethodsのインスタンスが1,000個ある場合でも、メモリに格納されている文字列「foo」のインスタンスは1つだけです)。

ただし、クラスで可変変数を使用すると、何をしているのかわからない場合に微妙なバグが発生する可能性があります。

検討:

class CustomizedMethods(object):
    class_var = {}

cm1 = CustomizedMethods()
cm2 = CustomizedMethods()

cm1.class_var['test'] = 'foo'
print cm2.class_var
  'foo'

cm2.class_var['test'] = 'bar'
print cm1.class_var
   'bar'
于 2012-09-11T04:27:03.140 に答える
0

してみてください

print cm1.__dict__ 
print cm2.__dict__ 

それは啓発されるでしょう...

cm2に属性を要求すると、最初にインスタンスの属性を調べ(名前と一致する場合)、次にクラス属性の中に一致する属性がないかどうかを調べます。

したがって、class_var1とclass_var2はクラス属性の名前です。

次も試してください。

cm2.__class__.class_var1 = "bar_foo" 
print cm1.class_var1 

何を期待しますか?

于 2012-09-11T08:30:18.930 に答える