Python/Tkinter: role of init / super in writing tkinter widgets as classes

Question:

In writing a tkinter root window as a class, I’m using the following code:

class RootWin(Tk):
  def __init__(self,...args go here...):
    super().__init__()

Although the code is correct, and works, I am uncomfortable writing code that I don’t fully understand, and despite the many explanations I have come across, none have clarified this for me.

I understand that the line class RootWin(Tk): indicates that I am creating a class called RootWin that inherits from Tk. In the next line, self refers to the instance of this class I will create later in my code, and the args specify the parameters I want to pass to this specific instance. That much is very clear.

Then, the explanations I’ve come across indicate that super().__init__() runs the init method of Tk (the parent class).

But why is it necessary to run the init method of the Tk class? If class RootWin(Tk) already indicates that my new RootWin class inherits from Tk, then why would anything more be required?

Perhaps the best way to pose this question is to ask it in three explicit parts, and request three answers, with apologies, if that’s asking a lot. I really want to understand this!

Question 1: What is accomplished by the line

class RootWin(Tk):

Question 2: What is accomplished by the line

def __init__(self,...args go here...):

Question 3: what is accomplished by the following line that has not already been accomplished by the two previous lines?

super().__init__()

Any advice appreciated.

Asked By: fmex

||

Answers:

But why is it necessary to run the init method of the Tk class?

Your own class has some initialization it performs, correct? There is code in your __init__ that must run for your class to be useful. This is where, for example, you would create other widgets for your app, variables, etc.

The tkinter base classes are the same way. They have code in their own __init__ method that must be run for the class to be useful. This code doesn’t run automatically if you create your own __init__. Therefore, you must call it so that the widget is properly initialized.

Question 1: What is accomplished by the line class RootWin(Tk):

Answer: it begins the definition of a new class name RootWin that inherits from the class Tk

Question 2: What is accomplished by the line def __init__(self,...args go here...)

Answer: it defines a method that is automatically called by python when you create an instance of your custom class. It also defines the arguments that your function may require.

When you do foo = RootWin(), python will automatically call RootWin.__init__ and pass in the instance (self) as the first argument. The rest are to be supplied by the caller.

Question 3: what is accomplished by the following line that has not already been accomplished by the two previous lines? super().__init__()

Answer: First, it has not been accomplished by the two previous lines. Because of the two previous lines, python will not automatically call the __init__ method of the base class. That responsibility becomes yours when you define a custom __init__. When you call super().__init__() you are explicitly requesting that the __init__ method of the base class be called.

The advantage to requiring you to explicitly call it is that you now have a choice of when or if to call it. While you almost always should, you might choose to do some custom initialization either before or after the base class has been initialized.

Note that none of this is unique to tkinter. This is how all python objects work.

Answered By: Bryan Oakley
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.