0

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.

1

3 Answers 3

4

several issues:

  • python 3 syntax for super: super().__init__(name, sound)
  • name mangling: instance variables starting with __ (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)?
  • and what are the class variables (_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)
Sign up to request clarification or add additional context in comments.

Comments

1

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, i.e. adding _ClassName in front of all attributes with two leading underscores. This prevents the inheritance you do from working.

2 Comments

Thanks Mike.It helped
This is Python's way to create something that can be use similarly to private attributes in other languages.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.