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?
Inheritance allows us to define a class that inherits all the methods and properties from another class. Parent class is the class being inherited from, also called base class. Child class is the class that inherits from another class, also called derived class.
Inheritance in Python Inheritance is a powerful feature in object oriented programming. It refers to defining a new class with little or no modification to an existing class. The new class is called derived (or child) class and the one from which it inherits is called the base (or parent) class.
In Python, property() is a built-in function that creates and returns a property object. The syntax of this function is: property(fget=None, fset=None, fdel=None, doc=None)
Inheritance is a process of obtaining properties and characteristics(variables and methods) of another class. In this hierarchical order, the class which inherits another class is called subclass or child class, and the other class is the parent 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.
Attribute names prefixed with a double underscore are treated specially by the compiler and you should avoid them until you understand Python better.
Most Python programmers don't know why they are special and they can still live an happy and productive programming life. They're also objectively ugly... don't you think?
Note also that in Python you don't start using getter and setter just for the fun of it. Simply start with a data member and only migrate to properties when (and only if) needed. Writing code for a getter that simply returns the member and for a setter that simply mutates it is nonsense. When (and if) you will need to do special processing on member access change them to properties, and there will be no need to change the code using your class.
On the technical explanation side Python simply adds the class name to attributes starting with a double underscore to avoid unwanted clashes with identically named attributes in other classes. This kind of problem is however not so common and that's why most Python programmers never had the necessity of this feature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With