2012-11-15 16 views
31

私は、子クラスがその親から継承するクラス変数を変更したいと思っています。Pythonで継承されたクラス変数の変更

私はの線に沿って何かやりたい:

class Parent(object): 
    foobar = ["hello"] 

class Child(Parent): 
    # This does not work 
    foobar = foobar.extend(["world"]) 

を、理想的に持っている:

Child.foobar = ["hello", "world"] 

私が行うことができます。その後、

class Child(Parent): 
    def __init__(self): 
     type(self).foobar.extend(["world"]) 

が、私はインスタンス化するたびにChildのインスタンス "world"がリストに追加されますが、これは望ましくありません。私はに、さらにそれを修正することができます:

class Child(Parent): 
    def __init__(self): 
     if type(self).foobar.count("world") < 1: 
      type(self).foobar.extend(["world"]) 

が、それが動作する前に、私が子供のインスタンスをインスタンス化する必要がありますので、これはまだハックです。

良い方法がありますか?

答えて

35

は、親クラスのリストを変更しない:

class Child(Parent): 
    foobar = Parent.foobar + ['world'] 

これは継承とは独立して動作することに注意してください。これはおそらく良いことです。

+1

これは幻想的で簡単です!また、子の属性の開始値が親の属性と同じでなければならない場合は、 'from copy import deepcopy;を使用すると便利です。 foob​​ar = deepcopy(Parent.foobar) ' – zen11625

16

クラス変数に可変値を使用しないでください。 __init__()インスタンス初期化子を使用して、代わりにインスタンスにそのような値を設定します。

class Parent(object): 
    def __init__(self): 
     self.foobar = ['Hello'] 

class Child(Parent): 
    def __init__(self): 
     super(Child, self).__init__() 
     self.foobar.append('world') 

そうでなければ何foobarリストはなく、サブクラスを持つだけでなく、だけではなく、インスタンス間で共有されることで起こります。

いずれの場合でも、可変クラス変数を使用してインスタンス間で状態を共有したい場合でも、親クラスの変数を変更しないでください。

class Parent(object): 
    foobar = ['Hello'] 

class Child(Parent): 
    foobar = Parent.foobar + ['world'] 

新しいfoobar変数はChildクラス用に作成されます。名前にのみ割り当ては、新しい変数を作成します。代入を使用すると、新しいリストインスタンスが作成され、Parent.foobarの変更可能性は影響を受けません。

このような場合はネストされた変数を使用してください。必要に応じてcopyモジュールを使用してディープコピーを作成します。 (あなただけの場所でそれを変更したり、そこに期待値を入れることができますので、そもそも無意味なようだ)あなたはサブクラスで別のリストを持つようにしたいと仮定し

関連する問題