Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python classes: Inheritance vs Instantiation

I'm creating a GUIclass that uses Frame() as its base class.

In my GUIclass’s init method I want to create a Frame widget

Right now I have:

class GUIclass(Frame):
    def __init__(self, parent):
        frame = Frame(self, parent)   

But I've seen this elsewhere for the third line:

Frame.__init__(self, parent)   

I'm new to programming, python and definitely inheritance and I wanted to know if I understand the difference between the two correctly. I did a lot of researching and reading, I promise, but I couldn't quite find anything that made it completely clear:

In the first situation I don't call the init method as I created a Frame object (frame) and when an object is created its init method is called implicitly by python.

In the second scenario, one is calling the init method on the class (which I believe is totally legit?) because a Frame object wasn't created, so therefore wouldn't do it automatically.

Is that right?

I've also seen:

frame = Frame.__init__(self, parent)   

which really threw me off. Is this just someone doing something redundant or is there a reason for this?

Thank you for your help, I want to take it slow for now and make sure I fully understand any and every line of code I write as I go rather than writing and running a whole program I half understand.

like image 923
Burkely91 Avatar asked May 15 '15 22:05

Burkely91


People also ask

What is the difference between inheritance and instantiation?

To address your question... inheritance and instantiatian are completely different concepts and are not provided to achieve the same at all. You inherit from a class to add more functionality without rewriting the entire class, among other things. You instantiate a class to use its functionality.

What is class instantiation in Python?

In short, Python's instantiation process starts with a call to the class constructor, which triggers the instance creator, . __new__() , to create a new empty object. The process continues with the instance initializer, . __init__() , which takes the constructor's arguments to initialize the newly created object.

Can inheritance be instantiated?

If a superclass is defined in a path of the inheritance tree using the addition CREATE PRIVATE, outside consumers cannot instantiate a subclass, and a subclass cannot even instantiate itself because it has no access to the instance constructor of the superclass.

What does __ class __ mean in Python?

__class__ is an attribute on the object that refers to the class from which the object was created. a. __class__ # Output: <class 'int'> b. __class__ # Output: <class 'float'> After simple data types, let's now understand the type function and __class__ attribute with the help of a user-defined class, Human .


1 Answers

You should call

super(GUIclass, self).__init__(parent)

This is the proper way to call (all) your inherited __init__() method(s). It has in many cases identical results compared to the mentioned

Frame.__init__(self, parent)

which only lacks the abstraction concerning the inheritance relationships and states the class Frame as the one and only class whose __init__() method you might want to call (more about that later).

The also mentioned

frame = Frame(self.parent)

is wrong in this context. It belongs to another pattern of object relationship, namely contents relationship instead of inheritance relationship (which you aim at). It will create a new object of class Frame instead of initializing the Frame parts of yourself; in inheritance relationships you are a Frame, so you have to initialize yourself as one as well as initializing your specialized parts (which is done in the rest of your __init__() method). In contents relationship models you merely have a Frame.

Now, what about that "slight" difference I mentioned above between calling super(GUIclass, self).__init__(parent) and Frame.__init__(self, parent)?

To understand that you need to dig deeper into inheritance relationships and the various possibilities these offer, especially with multiple inheritance.

Consider a diamond-shaped relationship model which looks like this:

          Frame
          /   \
    GUIclass  SomeOtherClass
          \   /
       AnotherClass

In your current scenario you only have the top left two classes, but one never knows what's going to come, and you should always code in a way so that the next user of your code keeps all options.

In this diamond-shaped pattern you have AnotherClass which inherits GUIClass and SomeOtherClass which in turn both inherit Frame.

If you now use the pattern Frame.__init__(self, parent) in both GUIclass and SomeOtherClass, then calling their __init__() methods from the __init__() method of AnotherClass will result in a doubled calling of the Frame's __init__() method. This typically is not intended, and to take care that this does not happen, the super call was invented. It takes care that a decent calling order calls each of the __init__() methods only and exactly once.

like image 167
Alfe Avatar answered Sep 28 '22 03:09

Alfe