Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grandchild inheriting from Parent class - Python

I am learning all about Python classes and I have a lot of ground to cover. I came across an example that got me a bit confused.

These are the parent classes

Class X
Class Y
Class Z

Child classes are:

Class A (X,Y)
Class B (Y,Z)

Grandchild class is:

Class M (A,B,Z)

Doesn't Class M inherit Class Z through inheriting from Class B or what would the reason be for this type of structure? Class M would just ignore the second time Class Z is inherited wouldn't it be, or am I missing something?

like image 638
Ernie Peters Avatar asked Mar 16 '17 15:03

Ernie Peters


People also ask

How do you inherit a child class from parent class in Python?

Use the super() Function By using the super() function, you do not have to use the name of the parent element, it will automatically inherit the methods and properties from its parent.

When a child class inherits from a parent class this type of inheritance is called?

Single inheritance This is a form of inheritance in which a class inherits only one parent class. This is the simple form of inheritance and hence also referred to as simple inheritance.

Do child classes inherit methods Python?

Child classes inherit the methods of the parent class it belongs to, so each child class can make use of those methods within programs.

Can parent class inherit the properties of child class?

Inheritance concept is to inherit properties from one class to another but not vice versa. But since parent class reference variable points to sub class objects. So it is possible to access child class properties by parent class object if only the down casting is allowed or possible....


1 Answers

Class M would just inherit the Class Z attributes twice (redundant) wouldn't it be, or am I missing something?

No, there are no "duplicated" attributes, Python performs a linearization they can the Method Resolution Order (MRO) as is, for instance, explained here. You are however correct that here adding Z to the list does not change anything.

They first construct MRO's for the parents, so:

MRO(X) = (X,object)
MRO(Y) = (Y,object)
MRO(Z) = (Z,object)

MRO(A) = (A,X,Y,object)
MRO(B) = (B,Y,Z,object)

and then they construct an MRO for M by merging:

MRO(M) = (M,)+merge((A,X,Y,object),(B,Y,Z,object),(Z,object))
       = (M,A,X,B,Y,Z,object)

Now each time you call a method, Python will first check if the attribute is in the internal dictionary self.__dict__ of that object). If not, Python will walk throught the MRO and attempt to find an attribute with that name. From the moment it finds one, it will stop searching.

Finally super() is a proxy-object that does the same resolution, but starts in the MRO at the stage of the class. So in this case if you have:

class B:

    def foo():
        super().bar()

and you construct an object m = M() and call m.foo() then - given the foo() of B is called, super().bar will first attempt to find a bar in Y, if that fails, it will look for a bar in Z and finally in object.

Attributes are not inherited twice. If you add an attribute like:

self.qux = 1425

then it is simply added to the internal self.__dict__ dictionary of that object.

Stating Z explicitly however can be beneficial: if the designer of B is not sure whether Z is a real requirement. In that case you know for sure that Z will still be in the MRO if B is altered.

like image 96
Willem Van Onsem Avatar answered Nov 14 '22 21:11

Willem Van Onsem