Why can't call all __init__ when super() with Multiple Inheritance? - python-3.x

Show the code:
class state():
def __init__(self):
print('in the state class')
self.state = "main state"
class event():
def __init__(self):
print("in the event class")
self.event = "main event"
class happystate(state,event):
def __init__(self):
print('in the happy state class')
super(state,self).__init__()
super(event,self).__init__()
happystate has two base class--state and event,initialize the happystate.
a = happystate()
in the happy state class
in the event class
Why can't call state class?

If you don't use super().__init__() in other classes, and you have multiple inheritance, python stops running other __init__ methods.
class state():
def __init__(self):
super().__init__()
print('in the state class')
self.state = "main state"
class event():
def __init__(self):
super().__init__()
print("in the event class")
self.event = "main event"
class happystate(state,event):
def __init__(self):
print('in the happy state class')
super().__init__()
I am adding some references:
From Raymond Hettinger
StackOverflow

As MisterMiyagi say that super(state,self).init does not mean "init on the super class which is state", it means "init on the super class which is in self's mro after state".
We can remove all the super().__init__() in class state and event with such other way as below:
class state():
def __init__(self):
print('in the state class')
self.state = "main state"
class event():
def __init__(self):
print("in the event class")
self.event = "main event"
class happystate(state,event):
def __init__(self):
print('in the happy state class')
super(happystate,self).__init__()
super(state,self).__init__()
Initialize the class happystate:
>>> x = happystate()
in the happy state class
in the state class
in the event class
>>> x.state
'main state'
>>> x.event
'main event'

Related

How to let sibling windows accept event?

I write a simple window, when cursor in QLineEdit and press Enter Key, I want the QGraphicsRectItem, QGraphicsScene, QGraphicsView and QWidget also accept QKeyEvent or MyEvent(customize event).I have no idea to do it,Could someone have good method to do this?
Code Sample
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MyEvent(QEvent):
Type = QEvent.registerEventType()
def __init__(self):
super().__init__(MyEvent.Type)
self._data = "test"
class Item(QGraphicsRectItem):
def __init__(self):
super().__init__()
self.setRect(0 ,0, 100, 100)
self.setBrush(Qt.red)
self.setFlags(QGraphicsItem.ItemIsFocusable)
def keyPressEvent(self, event: QKeyEvent) -> None:
print("Item KeyPress", event.key())
return super().keyPressEvent(event)
class Scene(QGraphicsScene):
def keyPressEvent(self, event: QKeyEvent) -> None:
print("Scene KeyPress", event.key())
return super().keyPressEvent(event)
class View(QGraphicsView):
def keyPressEvent(self, event: QKeyEvent) -> None:
print("View KeyPress", "do something work here", event.key())
return super().keyPressEvent(event)
class MainWindow(QWidget):
def __init__(self):
super().__init__()
lay = QVBoxLayout()
view = View()
scene = Scene()
scene.addItem(Item())
view.setScene(scene)
lay.addWidget(view)
lay.addWidget(QLineEdit("Cursor In here, post Enter Event to QGraphicsView"))
self.setLayout(lay)
self.show()
self.view = view
def keyPressEvent(self, e: QKeyEvent) -> None:
print("QWidget KeyPress", e.key())
# myEvent = MyEvent()
# QApplication.postEvent(myEvent)
return super().keyPressEvent(e)
app = QApplication([])
m = MainWindow()
app.exec()
How let others item also get the event?

Inheritance with python unittest

I have two unittest classes in the same file which look like this:
class A(unittest.TestCase):
def some_fun(param):
# Set class parameters
self.foo = param + 100
...
def some_fun2():
do_something with self.foo
self.assertEqual(self.foo,<check>)
def some_fun3():
do_something
def setUp(self):
some_fun(some_foo1)
def test1(self):
some_fun2(some_foo1)
def tearDown(self):
some_fun3(some_foo1)
class B(unittest.TestCase):
def some_fun(param):
# Set class parameters
self.foo = param + 100
...
def some_fun2():
do_something with self.foo
self.assertEqual(self.foo,<check>)
def some_fun3():
do_something
def setUp(self):
some_fun(some_foo1)
def test1(self):
some_fun2(some_foo1)
def tearDown(self):
some_fun3(some_foo1)
I want to move some_fun, some_fun2, some_fun3 outside to reduce code repetition keeping in mind that these functions can have assert checks
What is the best way to do this? Im not sure how to do inheritance in this scenario
Edit:
I am facing this weird issue
class X(unittest.TestCase):
def __init__(self, foo):
print(foo) # why is foo=somefun
def test():
<something>
class A(X):
FOO = "SOMESTRING"
def setUp(self):
super().__init__(A.FOO)
def somefun(self):
self.test()
It can be like this:
class X(unittest.TestCase):
def some_fun(self, param):
# Set class parameters
self.foo = param + 100
...
def some_fun2(self):
do_something with self.foo
self.assertEqual(self.foo,<check>)
def some_fun3():
do_something
class A(X):
def setUp(self):
self.some_fun(some_foo1)
def test1(self):
self.some_fun2(some_foo1)
def tearDown(self):
self.some_fun3(some_foo1)
class B(X):
def setUp(self):
self.some_fun(some_foo1)
def test1(self):
self.some_fun2(some_foo1)
def tearDown(self):
self.some_fun3(some_foo1)
Inheritance rules apply normally here. Create a base class with the methods you want that inherits from TestCase:
class BaseTest(unittest.TestCase):
def some_fun(self):
...
def some_fun2(self):
...
Create A and B inheriting from BaseTest:
class A(BaseTest):
def test1(self):
...
class B(BaseTest):
def test2(self):
...

How to Access Outer class variables in Inner Class (Python)?

How to access the variables of the outer class in the Inner Class?
class Student:
def __init__(self,Name,rollNumber):
self.Name=Name
self.rollNumber=rollNumber
self.lap=self.Laptop()
def Show(self):
print(self.Name)
print(self.lap.show())
class Laptop:
def __init__(self):
self.brand = "Mac"
self.cpu = "i9"
self.ram = 16
def show(self):
return self.brand
#staticmethod
def Show():
return s1.Name
s1=Student("Teja",2)
print(s1.Name,s1.rollNumber)
s1.Show()
print(s1.lap.brand)
system=s1.lap
print(system.brand)
print(system.cpu)
print(system.show())
print(system.Show())

pyqt5 and multiple inheritance

I'd like to create a new class that inherits two subclasses of QWidget. I know multi-inheritance isn't possible in pyqt, but how could I manage to have the properties of both parent classes in one subclass?
What I wish I could do is as follows:
class A(QWidget):
def __init__(self, widget, parent=None):
widget.destroyed.connect(self.destroy_handler)
#pyqtSlot()
def destroy_handler(self):
pass
class B (A, QStatusBar):
def __init__(self, widget, parent=None):
A.__init__(self, widget)
QStatusBar.__init__(self, parent)
#pyqtSlot()
def destroyed_handler(self):
print("Destroyed")
I finally found how to do it: first of all, the problems came from A and QStatusBar inheriting QWidget. We can't change QStatusBar, so we must changer A.
A shouldn't inherit QWidget: so let's create another class, AInterface, like that:
class AInterface(QObject):
def __init__(self, a, parent=None)
super().__init__(parent=parent)
self.a = a
self.connect_signal()
def connect_signal(self, widget):
widget.destroyed.connect(self.handler)
#pyqtSlot()
def handler(self):
self.a.handler()
A has now the following implementation:
class A:
def __init__(self, widget):
a.widget = widget
a.interface = AInterface(self)
def handler(self):
pass
Thus, now we can create subclasses inheriting not only A but also any QObject, like this:
class B(QStatusBar, A):
def __init__(self, widget, parent=None):
QStatusBar.__init__(self, parent=parent, wiget=widget)
A.__init__(self, widget)
def handler(self):
self.show('Destroyed', 3000)
Notice the widget=widget in the constructor of QStatusBar: if we don't specify it, a TypeError is thrown...

How to debug pyqt signal/slot connections, probably threading issue

I have the following piece of example code of my problem. Running this, I would expect that (if you type something in the lineedit) the A.updateValue slot would be called twice and thus show 'a.updatevalue called' and 'a2.updatevalue called'
However, it is only called once, namely for the self.a2 object and not for the self.a object, the latter which is sent from a worker thread to the GUI thread. How can I fix this so that this piece of code also triggers the slot for the self.a object?
Thank you,
David
import os, sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class A(QObject):
def __init__(self, name):
QObject.__init__(self)
self.name = name
def updateValue(self, value):
print(self.name + ".updatevalue called")
class workerthread(QThread):
def __init__(self, parent=None):
QThread.__init__(self, parent)
def run(self):
a = A('a')
QObject.emit(self, SIGNAL("mySignal"), a)
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.centralwidget = QWidget(self)
self.hbox = QHBoxLayout()
self.centralwidget.setLayout(self.hbox)
def update(self, a):
self.a = a
edit = QLineEdit("", self)
self.hbox.addWidget(edit)
edit.textChanged.connect(self.a.updateValue)
self.a2 = A('a2')
edit.textChanged.connect(self.a2.updateValue)
if __name__ == "__main__":
app = QApplication(sys.argv)
gui = Main()
worker = workerthread()
worker.connect(worker, SIGNAL('mySignal'), gui.update)
worker.start()
gui.show()
sys.exit(app.exec_())
Define a when you initialize workerThread
class workerthread(QThread):
def __init__(self, parent=None):
QThread.__init__(self, parent)
self.a = A('a')
def run(self):
QObject.emit(self, SIGNAL("mySignal"), self.a)

Resources