Trouble understanding a line of code in PyQt - python

I am trying to learn PyQt on my own from rapid gui programming with python and qt and having trouble understanding the meaning/requirement of below line of code mentioned in one of the example in the book.
class Form(QDialog):
def __init__(self,parent=None):
super(Form,self).__init__(parent) # Trouble understanding here
So, my question is what is the need of super(Form,self).__init__(parent) or what purpose it is trying to full fill in this code.

Take a look at the documentation of super():
Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped.
So basically this line of code:
super(Form,self).__init__(parent)
finds the "closest" set __init__() method in classes from which current class (Form) is inheriting and initiates self object using this method and passing parent as the first argument.

Related

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

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

How is this execute function referenced in this code?

I am a Java programmer that is new to Python. I am having trouble understanding the syntax of the following code from the pymodbus repo in GitHub. Where is the function defined?
self.execute(request)
The reason I am confused is that AFAIK self refers to variables and functions of the current class, even inherited ones. There is no function defined in the ModBusClientMixIn class, nor the class inherit from any other class. So where is it coming from?
There is an execute function defined in the ReadCoilsRequest class, but to invoke that why would you need self? Also, where is context(a variable in the execute function argument list) coming from?
Would really appreciate if someone can help me understand the syntax.
It's a mixin which is used on classes which do define an execute method, e.g.:
class ModbusClientProtocol(protocol.Protocol, ModbusClientMixin):
A mixin adds methods to other classes and is not supposed to be used by itself.
If you wanted to type-annotate it properly, it would have to be something like:
class Executable(ABC):
#abstractmethod
def execute(self):
pass
class ModBusClientMixin:
def read_coils(self: Executable, address, count=1, **kwargs):
# ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
# Expects self to conform to Executable interface,
# i.e. to be used in a class that implements execute().
self.execute()
Since Python heavily relies on duck-typing and type annotations are a relatively recent addition, they're often omitted and replaced by verbose documentation, or it is expected that developers recognise the purpose of mixins, or that it's such an internal implementation detail that it hasn't been explicitly documented.
This is a special case. You are right, that execute has to be defined somewhere.
But in this case, execute is implemented by a child class that derives from ModBusClientMixIn.
You would get an error if you were to create an instance of ModBusClientMixIn directly, because it does not implement execute.
Look at the implementations of ModbusClientProtocol or BaseModbusClient for example, they both have an execute method.

OnInit and __init__ in wxPython

I am learning wxPython. In one of the examples, the code is like follows:
import wx
class App(wx.App):
def OnInit(self):
frame = wx.Frame(parent=None, title = 'bare')
frame.Show()
return True
app=App()
app.MainLoop()
And I noticed that class App has no constructor but a function OnInit. As far as I know, Python classes are constructed with __init__ function.
So, is OnInit functions are for specific classes? Or it is another type of constructor?
Please forgive my ignorance since I am new to this. Thanks.
According to wx.App.__init__ documentation:
You should override OnInit to do applicaition initialization to ensure
that the system, toolkit and wxWidgets are fully initialized.
-> OnInit method is only for classes that derive wx.App.
Assuming you got the code from "wxPython in Action" book- good book would recommend,
It goes on to say (Im sure you have red this by now)...
Notice that we didn’t define an init()method for our application
class. In Python, this means that the parent method,
wx.App.init(), is automatically invoked on object creation. This
is a good thing. If you define an init() method of your own, don’t
forget to call the init()of the base class, like this:
class App(wx.App):
def __init__(self):
# Call the base class constructor.
wx.App.__init__(self)
# Do something here...
If you forget to do so, wxPython won’t be initialized and your OnInit()method won’t get called.

Python: An object constructor calls itself

I have encountered the following code. An object constructor calls itself:
class StatusMixin(object):
def __init__(self):
super(StatusMixin, self).__init__()
self.does_something()
Is there any practical reason why it is implemented like this? I think people use thesuper method only in the context of multiple inheritance.
You mention multiple inheritance. This class is described as a mixin: that is, it's specifically intended to be used in the case of multiple inheritance. It will be one of the elements in a class hierarchy, but not the top or the bottom. That's why it calls super - the next item in the method resolution order will not in practice be object, but some other class.
Consider this hierarchy:
class Super(object):
pass
class Sub(StatusMixin, Super)
pass
and examine Sub.mro():
[__main__.Sub, __main__.StatusMixin, __main__.Super, object]
So you see that here the result of the super call in StatusMixin is not object at all, but Super.

Different ways of using __init__ for PyQt4

So... I'm working on trying to move from basic Python to some GUI programming, using PyQt4. I'm looking at a couple different books and tutorials, and they each seem to have a slightly different way of kicking off the class definition.
One tutorial starts off the classes like so:
class Example(QtGui.QDialog):
def __init__(self):
super(Example, self).__init__()
Another book does it like this:
class Example(QtGui.QDialog):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
And yet another does it this way:
class Example(QtGui.QDialog):
def__init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
I'm still trying to wrap my mind around classes and OOP and super() and all... am I correct in thinking that the last line of the third example accomplishes more or less the same thing as the calls using super() in the previous ones, by explicitly calling the base class directly? For relatively simple examples such as these, i.e. single inheritance, is there any real benefit or reason to use one way vs. the other? Finally... the second example passes parent as an argument to super() while the first does not... any guesses/explanations as to why/when/where that would be appropriate?
The first one simply doesn't support passing a parent argument to its base class. If you know that you'll never need the parent arg, that's fine, but this is less flexible.
Since this example only has single inheritance, super(Example, self).__init__(parent) is exactly the same as QtGui.QDialog.__init__(self, parent); the former uses super to get a "version" of self that calles QtGui.QDialog's methods instead of Example's, so that self is automatically included, while the latter directly calls the function QtGui.QDialog.__init__ and explicitly passes the self and parent arguments. In single inheritance there's no difference AFAIK other than the amount of typing and the fact that you have to change the class name if you change inheritance. In multiple inheritance, super resolves methods semi-intelligently.
The third example actually uses QWidget instead of QDialog, which is a little weird; presumably that works because QDialog is a subclass of QWidget and doesn't do anything meaningful in its __init__, but I don't know for sure.

Categories