I am new to python and I wasn't sure what I was doing was correct.
I have a base class A
and an inherited class B
.
class A(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
class B(A):
def __init__(self, name):
super(NominalValue, self).__init__(name)
@property
def name2(self):
return self.__name2
@name2.setter
def name2(self, n):
self.__name2 = n
def toString():
print self.__name + self.__name2
if __name__ == "__main__":
instance = B('name');
instance.toString()
When I run this it complains that class B
does not have any attribute __name
.
AttributeError: 'B' object has no attribute '_B__name'
I am clearly not doing the inheritance correctly. How do you treat properties to be correctly inherited and avoid repeating attributes in the inherited class?
Attributes that begin with two underscores like your __name
are signified as being private variables. There's no actual PROTECTION done to these (that is to say: if you can find it, you can access it), but they are name-mangled to be less easy to access. More information about that can be found on the docs page
Any identifier of the form
__spam
(at least two leading underscores, at most one trailing underscore) is textually replaced with_classname__spam
, whereclassname
is the current class name with leading underscore(s) stripped.
Because of this, even though you're inheriting A
's __name
attribute, you don't have an attribute __name
in any object of type B
. What you have is a _A__name
attribute. That's how the name-mangling works: __attributename
becomes _classname__attributename
You could use _name
instead, which is just a flag to future users that this isn't supposed to be public. Then your whole code should work.