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.
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.
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.
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.
__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 .
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.
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