2017-01-02 1 views
0

Это часть кода Python для изучения наследования.Ошибка атрибута при использовании функции super() в Python 3.5

class Animal(): 
    __name= None 
    __sound = None 

    def __init__(self, name , sound): 
     self.__name= name 
     self.__sound = sound 
    def ToString(self): 
     print ("The {} has the sound {}".format(self.__name , 
               self.__sound)) 


cat = Animal('Tiger' , 'roars') 
cat.ToString() 


class Panther(Animal): 
    __owner = None 

    def __init__(self , name ,sound ,owner): 
     self.__owner = owner 
     super(Panther ,self).__init__(name, sound) 
    def ToString(self): 
     print(self.__owner) 
     print(self.__name) 

leopard = Panther('Leopard' , 'roars' , 'Senegal') 
leopard.ToString() 

Но когда я пытаюсь запустить его в PyCharm, я получаю следующее сообщение об ошибке:

/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 /Users/venkat/PycharmProjects/PythonOneVideo/main.py The Tiger has the sound roars Senegal Traceback (most recent call last): File "/Users/venkat/PycharmProjects/PythonOneVideo/main.py", line 41, in leopard.ToString() File "/Users/venkat/PycharmProjects/PythonOneVideo/main.py", line 35, in ToString print(self.__name) AttributeError: 'Panther' object has no attribute '_Panther__name'

Process finished with exit code 1

Что случилось с вызовом конструктора суперкласса? Почему эта ошибка произошла и как ее решить? Любая помощь будет оценена по достоинству.

+0

Возможный дубликат [Смысл одно- и двойного подчеркивания перед именем объекта в Python] (http://stackoverflow.com/questions/1301346/the-mean-of-a-single-and-a-double-underscore-before-an-object-name-in-python) –

ответ

4

несколько вопросов:

  • питон 3 Синтаксис super: super().__init__(name, sound)
  • name mangling: переменные экземпляра, начинающиеся с __ (два символа подчеркивания) получит _ClassName, добавленный к ним. дочерние классы не смогут получить к ним доступ обычным способом.
  • ToString: почему бы и нет __str__ (и не печатать внутри __str__; просто верните str)?
  • и каковы переменные класса (_name и т. Д.) Для? почему бы просто не использовать их как переменные экземпляра (self._name)?

это работает автобус неполно ...

class Animal(): 
    # _name= None 
    # _sound = None 

    def __init__(self, name , sound): 
     self._name= name 
     self._sound = sound 

# def ToString(self): 
#  print ("The {} has the sound {}".format(self._name , 
#            self._sound)) 

    def __str__(self): 
     fmt = 'The {self._name} has the sound {self._sound}' 
     return fmt.format(self=self) 

cat = Animal('Tiger' , 'roars') 
print(cat) 

class Panther(Animal): 
    # _owner = None 

    def __init__(self , name ,sound ,owner): 
     self.__owner = owner 
     super().__init__(name, sound) 

# def ToString(self): 
#  # print(self._owner) 
#  print(self._name) 

leopard = Panther('Leopard' , 'roars' , 'Senegal') 
print(leopard) 
1

Удалите два ведущих подчеркивание из ваших атрибутов:

class Animal(): 
    name= None 
    sound = None 

    def __init__(self, name , sound): 
     self.name= name 
     self.sound = sound 
    def ToString(self): 
     print ("The {} has the sound {}".format(self.name , 
               self.sound)) 


cat = Animal('Tiger' , 'roars') 
cat.ToString() 


class Panther(Animal): 
    owner = None 

    def __init__(self , name ,sound ,owner): 
     self.owner = owner 
     super(Panther ,self).__init__(name, sound) 
    def ToString(self): 
     print(self.owner) 
     print(self.name) 

leopard = Panther('Leopard' , 'roars' , 'Senegal') 
leopard.ToString() 

Выход:

The Tiger has the sound roars 
Senegal 
Leopard 

Два ведущих подчеркивания сделать ваши атрибуты "частный". Это делается моим name mangling, то есть добавлением _ClassName перед всеми атрибутами с двумя ведущими символами подчеркивания. Это предотвращает наследование, которое вы делаете с работы.

+0

Спасибо Mike.It помогло –

+0

Это способ Python создать что-то, что может использоваться аналогично частным атрибутам на других языках. –

0

Ваша ошибка связана с именем mangling. Python выполняет, когда вы добавляете имя переменной с __. Если вы просто использовать имена без двойной трейлинг подчеркивает, это работает отлично:

class Animal(): 
    def __init__(self, name , sound): 
     self._name= name 
     self._sound = sound 
    def ToString(self): 
     print ("The {} has the sound {}".format(self._name , 
               self._sound)) 


cat = Animal('Tiger' , 'roars') 
cat.ToString() 


class Panther(Animal): 

    def __init__(self , name ,sound ,owner): 
     self._owner = owner 
     super(Panther ,self).__init__(name, sound) 
    def ToString(self): 
     print(self._owner) 
     print(self._name) 

и печатает:

>>> leopard = Panther('Leopard' , 'roars' , 'Senegal') 
>>> leopard.ToString() 
The Tiger has the sound roars 
Senegal 
Leopard