2016-05-06 3 views
2

Мне не удалось найти ответы на это или, может быть, я использую неправильную номенклатуру в своем поиске. Если у меня есть что-то вроде:Можно ли неявно назначать атрибуты классу из унаследованного класса?

class testone(object): 
    def __init__(self): 
     self.attone = None 
     self.atttwo = None 
     self.attthree = None 

class testtwo(testone): 
    def __init__(self): 
     self.attfour = None 

И я:

a = test() 
print dir(a) 

b = testtwo() 
print dir(b) 

Можно видеть, что a будет иметь все это атрибуты определены как None но b только будет attfour определено, хотя он унаследовал класс testone. Я это понимаю, но возможно ли, что b имеют все атрибуты, унаследованные от a, неявно определенные также при создании экземпляра?

Я прошу b/c У меня есть классы, которые имеют десятки атрибутов, которые наследуются от классов с сотнями атрибутов, и мне нужно, чтобы каждый атрибут был определен, даже если он имеет тип None, так что мне не нужно беспокоиться о проверке наличия атрибута до сопоставления его с моим объектом на таблицу базы данных. Я стараюсь не писать столько кода. Если есть способ сделать это, я сохраняю более тысячи строк кода в своих определениях классов или могу просто проверить, существует ли каждый атрибут до сопоставления объекта с моей таблицей, но это много кода, а также пару тысяч атрибутов для проверки.

+0

Вы заменили '__init__' метод в подклассе; вы хотите вызвать * переопределенную * версию. 'super() .__ init __()' может сделать это (Python 3) или 'super (testtwo, self) .__ init __()' (оба Python 2 и 3). –

+0

@MartijnPieters не уверен, как это дубликат этого вопроса, но хорошо. Мой вопрос не спрашивает, как «вызвать метод родительского класса» или атрибут. Мой вопрос задает вопрос о том, что все атрибуты родительских классов неявно определены при создании экземпляра дочернего класса. Также этот вопросник уже знает о супер-решении. Я не знал о super(), поскольку он упоминается только один раз в [классе наследования doc] (https://docs.python.org/2/tutorial/classes.html#inheritance), а затем только при обсуждении множественного наследования, которое мой вопрос не имел никакого отношения. – btathalon

+1

Вам необходимо вызвать родительский метод '__init__'. Я читал это как «* как» я вызываю родительский метод __init__', а не «* должен» я вызываю родительский метод «__init__»? », На который ответ:« да, потому что этот метод устанавливает эти атрибуты , ничего больше". –

ответ

3

Да, но поскольку вы переопределили __init__ в производном классе, вам нужно будет явно ввести следующий класс в mro (родительский или родственный класс).

class testone(object): 
    def __init__(self): 
     self.attone = None 
     self.atttwo = None 
     self.attthree = None 

class testtwo(testone): 
    def __init__(self): 
     self.attfour = None 
     super(testtwo, self).__init__() # on python3 just use super() 

Для получения более подробной информации о наследовании, читать документы на super.

Примечание: Я предположил, что вы означали для testtwo наследовать testone в вашем вопросе, и сделали это исправление.

+0

Да, вы правы, я намеревался наследовать «testone». Я только что исправил это. – btathalon

+0

Это было именно то, что мне нужно. Я прочитал документы python в [наследование классов] (https://docs.python.org/2/tutorial/classes.html#inheritance), прежде чем задавать это, но не было объяснений этого и единственное упоминание о super() случаев множественного наследования, поэтому я не нажимал на super() и не читал его документы, где он продолжает объяснять решение моей ситуации. – btathalon

0

Поскольку вы перегрузили testone.__init__, вам необходимо позвонить в super() в testtwo. Еще одна вещь, которую вы можете сделать, это взять __init__ переменные

class testone(object): 
    attone = None 
    atttwo = None 
    attthree = None 

class testtwo(testone): 
    attfour = None