Initialization of Multiple Inheritance in Python - python

I came across the following python code in which a class inherits from two parent classes. I am trying to understand the constructor of the class.
# wrapper.py:
#############
class EWrapper:
def __init__(self):
pass
...
# client.py
###########
class EClient(object):
def __init__(self, wrapper):
self.msg_queue = queue.Queue()
self.wrapper = wrapper
self.decoder = None
self.reset()
....
# Test.py
#########
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
Could someone kindly shed more light on EClient.__init__(self, self)? It's not clear to me the usage of two selfs. How does python know which self is which?
What is the process of constructing an object of TestApp?

In the call EClient.__init__(self, self) the first self becomes that of EClient in EClient's def __init__(self, wrapper):. Next, as you may see, the second self gets bound to wrapper in that call. TestApp inherits EWrapper so it uses itself as a wrapper for EClient.

When initializing TestApp you are using the self of the EWrapper and then EClient since that is the order defined in the class.

Related

Python Fire module not showing COMMANDS in `-h`

I am using the python Fire module with an abstract parent class and a child class. Not all functions are abstract, some functions do not need to be replicated for each child:
parent class
from abc import ABC, abstractmethod
class Foo(ABC):
#abstractmethod
def __init__(self, val=None):
# some initialisations
#abstractmethod
def fun1(self, file=None):
# Some calls
def fun2(self):
# Non abastract func... Some calls
child class (test.py)
import fire
from foo import Foo
class Child(Foo)
def __init__(self, val=None):
super().__init__(val)
# some initialisations
def fun1(file='path/to/file')
# do some stuff
if __name__ == '__main__':
fire.Fire(Child)
when I run python CLI with python -m test --help I do not get any COMMANDS i.e. Fire is not recognising any functions to run. However it is recognising the parent global variables and init flags to set so why is this happening?
try passing it the instantiated object instead like they do here
fire.Fire(Child())

Passing Generic type to inner class

In this code, I want to pass the type T to the inner class Emitter.
T = TypeVar('T')
class MySignal(Generic[T]):
class Emitter(QtCore.QObject,Generic[T]):
signal = Signal(T)
def __init__(self):
super(MySignal.Emitter, self).__init__()
def __init__(self):
self.emitter = MySignal.Emitter[T]()
def emit(self,*args,**kw):
self.emitter.signal.emit(*args,**kw)
It doesn't behave as expected.
If I do
minMaxChanged=MySignal[tuple]()
Then minMaxChanged.emitter.__orig_class__.__args__[0] looks like T~ instead of tuple. The minMaxChanged class itself is as expected.
Generally, specifying Signal(typ) results in typ being the argument type expected to be passed to emit function. Consequently, in this case, Signal is called as if it were called without args, and calling emit with 1 argument fails since it expects no args.
I also expected the code
T = TypeVar('T')
class MySignal(Generic[T]):
class Emitter(QtCore.QObject):
signal = Signal(T)
def __init__(self):
super(MySignal.Emitter, self).__init__()
def __init__(self):
self.emitter = MySignal.Emitter()
def emit(self,*args,**kw):
self.emitter.signal.emit(*args,**kw)
to work. However, the exact same issue remains.
Update
Notice that this is not a redundant complication. This class (partially brought here) is meant to wrap a Qt Signal which can only be omitted from class that is a Qt class. It meant to provide a generic signal wrapper. See how to emit signal from a non PyQt class?
Trying double inheritance MySignal(QtCore.QObject, Generic[T]) resulted in a c++ style crash.
#ekhumu suggestion indeed works. I hoped for something prettier.
class MySignal:
def __init__(self,typ):
Emitter = type('Emitter', (QtCore.QObject,), {'signal': Signal(typ)})
self.emitter = Emitter()
def emit(self,*args,**kw):
self.emitter.signal.emit(*args,**kw)
def connect(self, slot):
self.emitter.signal.connect(slot)

accessing UI elements from another class in python

Example
function.py
class testClass(object):
def functionA(self):
#doSomething
self.Qlabel.clear()
main.py
class mainClass(object):
def __init__(self, parent = #something):
#initialize something
super(mainClass, self).__init__(parent)
self.setupUi(self)
self.Qlabel.clicked.connect(self.testFunc)
def testFunc(self):
import function as FT
FT.testClass().functionA(self)
I tried connecting my PyQt function.py to main.py. It keeps giving me this TypeError: functionA() takes exactly 1 argument (2 given).
If I take away the 'self' in so that it's FT.testClass().functionA(), then I get AttributeError: 'testClass' object has no attribute 'Qlabel'
I saw in PyQt : accessing elements from outside the class that it works with just using obj but not with classes.
I would like to understand how to fix this and also why my previous method doesn't work. Any help would be appreciated!
I have managed to get it working. The problem was basically in function.py, I was using self.Qlabel.clear() instead of object.Qlabel.clear(),
This is the working code.
function.py
class testClass(object):
def functionA(self, object):
#doSomething
object.Qlabel.clear()
main.py
class mainClass(object):
def __init__(self, parent = something):
#initialize something
super(mainClass, self).__init__(parent)
self.setupUi(self)
self.Qlabel.clicked.connect(self.testFunc)
def testFunc(self):
import function as FT
FT.testClass().functionA(self)
In the definition of functionA make one more Entry.
For e.g.
def functionA(self, mainClassObj):
#doSomething
self.Qlabel.clear()
Cause of the error is you're calling testclass function with one extra argument.Whereas you define it with one argument.
Note: You have to initiate Qlabel :
def functionA(self, mainClassObj):
#doSomething
from PyQt5.QtWidgets import QLabel
Qlabel().clear()
This should work for you.

Superclass __init__ not recognizing its kwargs

I'm trying to use the StoppableThread class presented as an answer to another question:
import threading
# Technique for creating a thread that can be stopped safely
# Posted by Bluebird75 on StackOverflow
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self):
super(StoppableThread, self).__init__()
self._stop = threading.Event()
def stop(self):
self._stop.set()
def stopped(self):
return self._stop.isSet()
However, if I run something like:
st = StoppableThread(target=func)
I get:
TypeError: __init__() got an unexpected keyword argument 'target'
Probably an oversight on how this should be used.
The StoppableThread class does not take or pass any additional arguments to threading.Thread in the constructor. You need to do something like this instead:
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self,*args,**kwargs):
super(threading.Thread,self).__init__(*args,**kwargs)
self._stop = threading.Event()
This will pass both positional and keyword arguments to the base class.
You are overriding init and your init doesn't take any arguments. You should add a "target" argument and pass it through to your base class constructor with super or even better allow arbitrary arguments via *args and *kwargs.
I.e.
def __init__(self,*args,**kwargs):
super(threading.Thread,self).__init__(*args,**kwargs)
self._stop = threading.Event()

How export methods with dbus in a extended class in python, inherited methods?

I have a top class and classes that extend the top class, but almost all methods from the child classes are from the top class (using inheritance, without reimplementation), so I don't have the methods in the child classes, how could I export them with dbus for each child class (with the name of each child class as part of dbus path)?
I will show a example code for clarify, my class structure is:
Window (main class)
|--WindowOne (child class)
|--WindowTwo
|--WindowThree
My interface for dbus is com.example.MyInterface and I would like to access each child class using: com.example.MyInterface.WindowOne, and for each child class I would like to access the methods, inclusive the inherited methods from the main class, like com.example.MyInterface.WindowOne.show and com.example.MyInterface.WindowOne.destroy.
In this code, I extend the child class 'WindowOne' with the 'Window' class, the methods show() and destroy() in the 'Window' are not re-implemented in 'WindowOne', but in this code I put the method show() to explain the problem, the way I get the code to work was this, I re-declare the method show() in child class, but this seems bad.
The big question maybe is: There is some way to use the decorator: #dbus.service.method('com.example.MyInterface.WindowOne') for classes (child classes in this case)?
The test source code:
# interface imports
from gi.repository import Gtk
# dbus imports
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
# Main window class
class Window(dbus.service.Object):
def __init__(self, gladeFilePath, name):
# ... inicialization
self.name = name
self.busName = dbus.service.BusName('com.example.MyInterface.', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, self.busName, '/com/example/MyInterface/' + self.name)
def show(self):
self.window.show_all()
def destroy(self):
Gtk.main_quit()
# Child window class
class WindowOne(Window):
def __init__(self, gladeFilePath):
Window.__init__(self, gladeFilePath, "WindowOne")
#dbus.service.method('com.example.MyInterface.WindowOne')
def show(self):
self.window.show_all()
if __name__ == "__main__":
DBusGMainLoop(set_as_default=True)
gladeFilePath = "/etc/interface.glade"
windowOne = WindowOne(gladeFilePath)
Gtk.main()
After some experimentation, I realize something essential, that I don't find before in documentation: The path for exported methods don't need to have the same path of exported object! Clarifing: If the method is not reimplemented in the child class (WindowOne), I don't need to export it in the child class using #dbus.service.method('com.example.MyInterface.WindowOne') , for example, I just need to export the method in the main class (Window) using: #dbus.service.method('com.example.MyInterface.Window')
So I just need to use a fixed path when export the method of the top class Window, see in the fixed code below.
# interface imports
from gi.repository import Gtk
# dbus imports
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
# Main window class
class Window(dbus.service.Object):
def __init__(self, gladeFilePath, name):
# ... inicialization
self.name = name
self.busName = dbus.service.BusName('com.example.MyInterface.', bus=dbus.SessionBus())
dbus.service.Object.__init__(self, self.busName, '/com/example/MyInterface/' + self.name)
#dbus.service.method('com.example.MyInterface.Window')
def show(self):
self.window.show_all()
#dbus.service.method('com.example.MyInterface.Window')
def destroy(self):
Gtk.main_quit()
#dbus.service.method('com.example.MyInterface.Window')
def update(self, data):
# top class 'update' method
# Child window class
class WindowOne(Window):
def __init__(self, gladeFilePath):
Window.__init__(self, gladeFilePath, "WindowOne")
#dbus.service.method('com.example.MyInterface.WindowOne')
def update(self, data):
# reimplementation of top class 'update' method
if __name__ == "__main__":
DBusGMainLoop(set_as_default=True)
gladeFilePath = "/etc/interface.glade"
windowOne = WindowOne(gladeFilePath)
Gtk.main()
In the code for call the bus method, I just use like below:
bus = dbus.SessionBus()
dbusWindowOne = bus.get_object('com.example.MyInterface', '/com/example/MyInterface/WindowOne')
showWindowOne = dbusWindowOne.get_dbus_method('show', 'com.example.MyInterface.Window')
updateWindowOne = dbusWindowOne.get_dbus_method('update', 'com.example.MyInterface.WindowOne')
The method show is called in the top class Window, but is executed in the object WindowOne that is a child class.
And the method update is called in the child class WindowOne, because it is reimplementing the top class method.

Categories