2016-03-20 2 views
3

Предположим, у меня есть класс с именем Test с элементами атрибута. Затем я создаю подкласс под названием Best. У кого есть метод, который изменяет элементы атрибутов классов. Но он даже изменяет Testitems, и я его должен изменить items только для Best.Наследование класса 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

Действительно ли 'Best' должен наследовать от' Test'? – 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'] 

Обратите внимание, что method_test работает на Best класса, когда вызывается из Best класса.

+0

Я создал новые предметы, и он работает! Спасибо. – les

1

Вы объявили items как атрибут самого суперкласса, так что все экземпляры теста и его подклассы будут иметь одинаковый список. Вместо этого объявите его в методе __ init __ теста, поэтому для каждого экземпляра есть один список.

В лучшем случае просто добавьте self.items, и будет обновлен список лучших экземпляров.

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

В Python вы можете получить то, что вы просите, используя «частные» члены ...

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 заменит имя __mine с _Base__mine при компиляции Base и с _Derived__mine при компиляции Derived.

Обратите внимание, что в Python, хотя это возможно в моем опыте, он не используется очень часто. Получение класса во многих случаях просто не требуется благодаря «утиному набору» и делегированию, что невозможно в таких языках, как C++ или Java.

+0

OK Я попробую. Спасибо. – les

+0

Это не совсем то, что я хотел, но это все еще помогает мне с разной вещью, спасибо. – les

0

Ваш код не соответствует описанию.

С одной стороны, Best не является подклассом Test.

Для другого Best.method() производит

NameError: name 'self' is not defined 

items является приписывать Test класса.

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

Test.items.

Как определено B.items дает AttributeError.

Даже если я изменю:

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

Best.method() не работает; method - метод экземпляра. Мне нужно использовать Best().method(). Но затем я получаю itemsAttributeError.

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

делает то, что вы описали. Best().method() изменяет Test.items - поскольку атрибут класса Test используется совместно с подклассом.

Как показано в других ответах, просто определяя items для Best разъединяет его значение из атрибута Test класса

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

Извините, я не тестировал пример кода. Я редактировал вопрос. Благодарю. – les

1

Ваш Best класс модифицирующих Test (который я предполагаю, что он должен быть наследующий), потому что Best Безразлично у него есть собственный список items. Когда вы обращаетесь к Best.items, вы получаете доступ к списку, где он унаследован от (то есть от Test класса). Если вы хотите другой список, вам нужно создать его в явном виде в подклассе Best:

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

    # ... 
Смежные вопросы