This is a piece of Python code to learn inheritance.
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()
But when I try to run it in Pycharm, I get the following error:
/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
What's wrong with calling the super class constructor? Why this error has happened and how to solve this? Any help would be appreciated.
several issues:
super
: super().__init__(name, sound)
__
(two underscores) will get _ClassName
prepended to them. child classes will not be able to access them the usual way. ToString
: why not __str__
(and do not print inside __str__
; just return a str
)? _name
etc) for? why not just have them as instance variables ( self._name
)? this works bus is incomplete...
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)
Remove the two leading underscore from your attributes:
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()
Output:
The Tiger has the sound roars
Senegal
Leopard
The two leading underscores make your attributes "private". This is done my name mangling , ie adding _ClassName
in front of all attributes with two leading underscores. This prevents the inheritance you do from working.
Your error stems from the name mangling Python performs when you prepend a variable name with __
. If you simply use names without the double trailing underscores, this works fine:
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)
and prints out:
>>> leopard = Panther('Leopard' , 'roars' , 'Senegal')
>>> leopard.ToString()
The Tiger has the sound roars
Senegal
Leopard
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.