Reputation: 93
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
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
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
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