2016-12-08 5 views
-1

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

AttributeError: 'Vulture' object has no attribute '_Bird__direction' 

я не уверен, что я сделал неправильно, и я надеюсь, что кто-то может помочь мне найти мою ошибку.

класс Vulture:

from bird import * 
class Vulture (Bird): 
    def __init__(self): 
     self.__hungry=True 
     self.__in_a_row=-1 
     self.__direction=DIRECTION_NORTH 

    def eat(self): 
     if self.__hungry: 
      self.__hungry=False 
      return True 
     else: 
      return False 

    def fight(self, opponent): 
     self.__hungry=True 
     return super(Bird, self).fight(self,opponent) 
    def get_color(self): 
     black 

Bird Класс:

from Critter import * 

class Bird (Critter): 
    def __init__(self): 
     self.__in_a_row=-1 #doesn't go north 3 times on first move if set to 0 
     self.__direction=DIRECTION_NORTH 

    def fight(self, opponent): 
     if opponent.__str__=="%": #roars at ants 
      return ATTACK_ROAR 
     else: 
      return ATTACK_POUNCE 

    def get_color(self): 
     return "blue" 

    def __str__(self): #uses the most recent direction to determine which character should be used 
     if (self.__direction==DIRECTION_NORTH or self.__direction==DIRECTION_CENTER): 
      return "^" 
     elif self.__direction==DIRECTION_EAST: 
      return ">" 
     elif self.__direction==DIRECTION_SOUTH: 
      return "V" 
     else: 
      return "<" 

    def get_move(self): 
     if self.__in_a_row<2: 
      self.__in_a_row+=1 
      return self.__direction 
     else: #Turning in the proper direction after it hits the end of the line 
      if self.__direction==DIRECTION_NORTH: 
       self.__direction=DIRECTION_EAST 
       self.__in_a_row=0 
       return self.__direction 
      elif self.__direction==DIRECTION_EAST: 
       self.__direction=DIRECTION_SOUTH 
       self.__in_a_row=0 
       return self.__direction 
      elif self.__direction==DIRECTION_SOUTH: 
       self.__direction=DIRECTION_WEST 
       self.__in_a_row=0 
       return self.__direction 
      elif self.__direction==DIRECTION_WEST: 
       self.__direction=DIRECTION_NORTH 
       self.__in_a_row=0 
       return self.__direction 

    def eat(self): 
     return False 

Я не думаю, что сам зверушка класс будет иметь важное значение в этом, и это довольно большой, поэтому я оставлю что с должности, если кто-то думает, что это может помочь.

+0

Можете ли вы предоставить код, в котором вы используете эти классы, а также класс «Critter»? –

ответ

0

См. Этот раздел на странице Private Variables в документации на Python.

Python обрабатывает переменные экземпляра, которые начинаются с двойных подчеркиваний специально, изменяя имя, чтобы сохранить их закрытыми для класса (даже частные из родительского класса). Когда вы вызываете метод Bird на свой класс Vulture, метод Bird ссылается на self.__direction: Фактически ссылается на переменную self._Bird__direction, которая отличается от переменной self._Vulture__direction, которую вы инициализируете в своем конструкторе Vulture __init__.

В частности:

v = Vulture() # initializes self._Vulture__direction only 
print(v)  # throws an exception -- v._Bird__direction isn't initialized 

Edit: Как @ShadowRanger указывает, соглашение в Python является префиксом с одним подчеркиванием эти переменные экземпляра или методы, которые предназначены, чтобы быть приватной для реализации, но свободный обмен между суперклассами и подклассами (т. е. аналогично protected в Java или C++). Специфическим языком таких переменных не является язык, это всего лишь сигнал для пользователей этого класса, что они не должны «путаться» с этими переменными или методами экземпляра.

Возможно, вы планировали __direction, __in_a_row и, возможно, даже __hungry (хотя последний не отображается в классе Bird). Если вы измените все эти префиксы двойного подчеркивания на отдельные символы подчеркивания, это должно устранить вашу проблему.

+0

Чтобы решить эту проблему, вы можете упомянуть, что переменные, соответствующие «защищенным» на других языках (доступные для всех классов в иерархии наследования, но не используемые другими), традиционно начинаются с одного '_', а не два. Два - это магия, а другая нет. – ShadowRanger

+0

Кажется, что все получилось, спасибо за помощь. – Denbus

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