2015-05-28 2 views
1

У меня есть базовый класс, куча подклассов, и для каждого из этих подклассов у меня есть еще один набор суб-подклассов. Например:Получить атрибут из суперкласса в python

class BaseClass(object): 
    def __init__(self): 
     with open(config.txt) as f 
      self.config_array = f.readlines() 

class FirstOrderSubClass(BaseClass): 
    def __init__(self, name): 
     self.name = name 

class SecondOrderSubClass(FirstOrderSubClass): 
    def __init__(self, name, version): 
     self.name = name 
     self.version = version 
     super(SecondOrderSubClass, self).__init__(self.name) 
     # needed to access self.config_array 
     print self.config_array 

Мне нужно, чтобы получить __init__() метод SecondOrderSubClass сделать следующее назначение: self.lines = self.config_array.

EDIT: добавлена ​​линия print self.config_array. Если я запускаю код, который я получаю:

TypeError: __getattr__() takes exactly 1 argument (2 given) 
+0

Вы уже наследующий атрибут, add 'super (FirstOrderSubClass, self) .__ init __()' в 'FirstOrderSubClass' –

ответ

3

Вы не можете получить доступ к self.config_array до BaseClass.__init__() побежал, чтобы установить атрибут.

Либо исправить FirstOrderSubClass, чтобы также вызвать базовый класс __init__ или назвать его напрямую.

Крепление FirstOrderSubClass, вероятно, лучший способ сделать это:

class FirstOrderSubClass(BaseClass): 
    def __init__(self, name): 
     super(FirstOrderSubClass, self).__init__() 
     self.name = name 

Однако ваш __init__ подпись метод не совпадает, так что вы не можете полагаться на кооперативном поведении здесь; как только вы добавите класс смешения в иерархию, все может и, возможно, сломается. См. *Python's super() is considered super! Раймондом Хеттингером, или его последующее описание PyCon presentation, чтобы объяснить, почему вы хотите, чтобы ваши подписи соответствовали друг другу.

Вызов несвязанного метода BaseClass.__init__ непосредственно (переходящая в self в явном виде) также будет работать:

class SecondOrderSubClass(FirstOrderSubClass): 
    def __init__(self, name, version): 
     super(SecondOrderSubClass, self).__init__(self.name) 
     self.version = version 
     BaseClass.__init__(self) 

Обратите внимание, что нет никакого смысла в присвоении self.name там, если вы собираетесь спросить FirstOrderSubClass.__init__ сделать точно такое же вещь.

Правильный способ использования super() - это для всех ваших методов как минимум принять все те же аргументы. Поскольку object.__init__() никогда не делает, это означает, что вам нужен класс дозорного, который не использует super(); BaseClass здесь будет хорошо. Вы можете использовать *args и **kw захватить любые дополнительные аргументы и просто игнорировать те, чтобы сделать совместные подклассы работы:

class BaseClass(object): 
    def __init__(self, *args, **kw): 
     with open(config.txt) as f 
      self.config_array = f.readlines() 

class FirstOrderSubClass(BaseClass): 
    def __init__(self, name, *args, **kw): 
     super(FirstOrderSubClass, self).__init__(*args, **kw) 
     self.name = name 

class SecondOrderSubClass(FirstOrderSubClass): 
    def __init__(self, name, version, *args, **kw): 
     super(SecondOrderSubClass, self).__init__(name, *args, **kw) 
     self.version = version 
+0

Спасибо за объяснение! Это именно то, чего мне не хватало. Если 'BaseClass .__ init__' не запускается, конечно, я не могу получить к нему ничего! Большое спасибо также за указание на разговор, я изучаю Python с нескольких месяцев, и я пытаюсь читать/смотреть все, что я нахожу. – rafforaffo

1

Вы должны вызвать FirstOrderSubClasssuper метод:

class BaseClass(object): 
    def __init__(self): 
     with open("config.example.txt",'w') as f: 
      f.write("Hello world") 
     with open("config.example.txt") as f: 
      self.config_array = f.readlines() 

class FirstOrderSubClass(BaseClass): 
    def __init__(self, name): 
     super(FirstOrderSubClass,self).__init__() 
     self.name = name 

class SecondOrderSubClass(FirstOrderSubClass): 
    def __init__(self, name, version): 
     self.name = name 
     self.version = version 
     super(SecondOrderSubClass, self).__init__(self.name) 
     # needed to access self.config_array 

grandchild = SecondOrderSubClass("peter",2.0) 
print grandchild.config_array 
##>>> 
##['Hello world'] 
Смежные вопросы