2016-03-20 11 views
3

属性アイテムを持つTestというクラスがあります。次に、Bestというサブクラスを作成します。クラス属性項目を変更するメソッドがあります。しかし、それはTestitemsとそれを修正するものも変更しますitemsBestのためだけです。Pythonクラスの継承 - ベースはサブクラスによって変更されます

class Test(): 
    items = [] 

class Best(Test): 
    def method(self): 
     type(self).items.append("a test") 

>>> Best().method() 
>>> Best.items 
["a test"] 
>>> Test.items 
["a test"]   # This is what I don't want. 
+0

「ベスト」は、「テスト」から継承されるはずですか? – Blckknght

+0

はい、私は私のサンプルコードをテストしませんでした、申し訳ありません。 – les

答えて

1

これを行うための唯一の可能な方法は、サブクラスに新しいitemsを作成することです - 他には意味この新しいリストですから来た?また、type(self)は冗長です。インスタンス上で属性を見つけることができない場合、検索機構はクラスの属性を検索します。さらに、インスタンスを必要としない場合は、メソッドをクラスメソッドとして宣言してください。

例えば、

class Test: 
    items = [] 
    @classmethod 
    def method_test(cls): 
     cls.items.append('test') 

class Best(Test): 
    items = [] 
    @classmethod 
    def method_best(cls): 
     cls.items.append('best') 

Test.method_test() 

assert Test.items == ['test'] 
assert Best.items == [] 

Test.items = [] 
Best.method_test() 
Best.method_best() 

assert Test.items == [] 
assert Best.items == ['test', 'best'] 

Bestクラスから呼び出さBestクラスのmethod_test作品という。

+0

私は新しいアイテムを作成し、それは動作します!ありがとうございました。 – les

1

あなたはそうテストし、それのサブクラスのすべてのインスタンスが同じリストを共有する、スーパークラス自体の属性としてitemsを宣言しました。代わりに、Testの__ init __メソッドで宣言してください。インスタンスごとに1つのリストがあります。

ベストでは、self.itemsに追加すると、Bestインスタンスのリストのみが更新されます。

あなたは「プライベート」のメンバーを使用して求めているものを手に入れることができますPythonで
class Test(object): 
    def __ init __(self) 
     self.items = [] 

class Best(Test): # Best must inherit from Test 
    def method(self): 
     self.items.append("a test") 
+0

これはクラスのインスタンスではない属性です。 – les

2

...

class Base(object): 
    def __init__(self): 
     self.__mine = 42 # note the double underscore 
    def baseMethod(self): 
     return self.__mine 

class Derived(Base): 
    def __init__(self): 
     Base.__init__(self) 
     self.__mine = 99 

    def derivedMethod(self): 
     return self.__mine 

obj = Derived() 
print(obj.baseMethod(), obj.derivedMethod()) ## ==> 42, 99 

コンパイルするときコンパイル時に Pythonは_Base__mineと名前__mineに置き換えられますので、これは動作しますコンパイル時にと_Derived__mineとなるとDerivedとなります。

しかし、これは私の経験では可能ですが、それほど頻繁には使用されません。多くの場合、クラスを派生させることは、C++やJavaなどの言語では不可能な、「ダックタイピング」と委任のおかげで必要なものではありません。

+0

私はお試しください。ありがとうございました。 – les

+0

それは私が欲しかったのは正確ではありませんが、それでも私はdiffiffentなもの、おかげで私を助けます。 – les

0

あなたのコードは、あなたが記述したものではありません。

Bestは、Testのサブクラスではありません。別のBest.method()については

NameError: name 'self' is not defined 

itemsTestクラス属性で生成します。

t = Test() 
t.items.append(1) 

Test.itemsを変更します。

B.itemsは、AttributeErrorとなります。

私は変更しても:

class Best(): 
    def method(self): 
     ... 

Best.method()は実行されません。 methodはインスタンスメソッドです。 Best().method()を使用する必要があります。しかし、私はitemsAttributeErrorを取得します。

​​

あなたが望むものは何ですか? Best().method()Testクラス属性がサブクラスと共有されているため、Test.itemsを変更します。単にBestためitemsを定義し、他の回答に示すように

はあなたのBestクラスはBest doesnのために(私はそれが継承されることになっていますと仮定)Testを変更している

class Best(Test): 
    items = ['other'] 
    ... 
+0

申し訳ありませんが、私はサンプルコードをテストしませんでした。私はその質問を編集した。ありがとう。 – les

1

Testクラス属性からその値を分離しますそれ自身のitemsリストがあります。 Best.itemsにアクセスすると、そこから継承されたリスト(つまりTestクラス)にアクセスしています。あなたが別のリストが必要な場合は、サブクラスBestで明示的に作成する必要があります。

class Best(Test): 
    items = [] # hide the inherited list with our own list 

    # ... 
関連する問題