GGinside
GGinside

Reputation: 93

Python Inheritance:Attribute error when using a parent method to print out a inherited variable

  1. I am new to python inheritance, and I met a simple issue just to print out variables.
  2. I have a parent class prints
class prints:
   def __init__(self):
       self.__name = ""
   def getName(self):
       return self.__name

class A(prints):
   def __init__(self):
       self.__name = "A"

a = A()
n = a.getName()

print(n)

I got an error

 AttributeError: 'A' object has no attribute '_prints__name'

Could someone help? Thanks!

Upvotes: 2

Views: 1112

Answers (3)

CodeEmpower
CodeEmpower

Reputation: 663

class prints:
   def __init__(self, name):
       self.name = ""

   def getName(self):
       return self.name

class A(prints):
   def __init__(self):
       self.name = "A"

 a = A()
 n = a.getName()

print(n)

refer to basics in python https://www.w3schools.com/python/python_inheritance.asp

Upvotes: -1

SVIS
SVIS

Reputation: 58

The problem is that you are using a variable with prefix __. Officially python does not have private variables, but when you use a var with prefix __, the it stored as _className__var,

If you peek inside a.__dict__:

a.__dict__
Out[9]: {'_A__name': 'A'}

So, when you do a.getName(), inheritance logic that you would expect kicks in that searches parent for getName by looking at prints.__dict__(which finds a match)

This would attempt to resolve __name of the parent, except in this case it would be looking to resolve it as _prints__name of self which is an instance of A.

This is called name mangling

Upvotes: 2

tdelaney
tdelaney

Reputation: 77397

Python doesn't implement private variables but it does help reduce the risk of name clashes with variables you'd like to keep private to a class. If your instance variable starts with two underscores, python will prepend the class name. See "name mangling" in Private Variables So, the prints __name variable is renamed _prints__name.

This method works, except when it doesn't. Inherited classes don't have a natural way to get to the variable. Generally this isn't a problem because it is class private after all. One way to use it is to call methods in the base class. In this case, you likely should have called the base class __init__ to set the variable. But if you want to use it directly, you can do self._prints__name.

class prints:
   def __init__(self):
       self.__name = ""
   def getName(self):
       return self.__name

class A(prints):
   def __init__(self):
       self._prints__name = "A"

a = A()
n = a.getName()

print(n)

Upvotes: 4

Related Questions