Child calling parent's method without calling parent's __init__ in python
<p>I have a program that have a gui in PyQt in the main thread. It communicates to a photo-detector and gets power readings in another thread, which sends a signal to the main thread to update the gui's power value.
Now I want to use a motor to automatically align my optical fiber, getting feedback from the photo-detector. </p>

<p>So I created a class that controls the motors, but I have to somehow pass the photo-detector readings to that class. First, I tried to access parent's power variable but it didn't work. 
Then I created a method in my gui to return the variable's value and tried to access it from the motor class. I got a problem saying that I couldn't use parent's method without using its <code>__init__</code> first. Is there a way to bypass it? I can't call the gui <code>__init__</code> again, I just want to use one of its methods from within the child class.</p>

<p>If there is an alternative way to do this, I'd be happy as well.</p>

<p>PS: I guess I can't give the child class the photo-detector object because it is in another thread, right? </p>

<p>--Edit--
The gui code is:</p>

<pre><code>class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    self.PDvalue = 0 #initial PD value
    self.PDState = 0 #control the PD state (on-off)
    self.PDport =  self.dialog.pm100d.itemText(self.dialog.pm100d.currentIndex()) #gets pot info

    def __init__(self):
    ... #a lot of other stuff
    self.nano = AlgoNanoMax.NanoMax('COM12') #creates the motor object
    self.nano_maxX.clicked.connect(self.NanoMaximizeX) #connect its fun to a buttom
    self.actionConnect_PM100D.triggered.connect(self.ActionConnect_PM100D) #PD buttom

    def NanoMaximizeX(self): 
        self.nano.maximize_nano_x() #uses motor object function

    def ActionConnect_PM100D(self):
        if self.PDState == 0: #check if PD is on
            self.PD = PDThread(self.PDState, self.PDport) #creates thread
            self.PD.valueupdate.connect(self.PDHandler) #signal connect
            self.PD.dialogSignal.connect(self.PDdialog) #create error dialog
            self.threads = []
            self.threads.append(self.PD)
            self.PD.start() #start thread
        else:
            self.PDState = 0
            self.PD.state = 0 #stop thread
            self.startpd.setText('Start PD') #change buttom name


   def PDHandler(self, value):
       self.PDvalue = value #slot to get pow from thread

   def ReturnPow(self):
       return self.PDvalue #return pow (I tried to use this to pass to the motor class)

   def PDdialog(self):
       self.dialog.set_instrument('PM100D') #I have a dialog that says error and asks you to type the right port
       if self.dialog.exec_() ==  QtGui.QDialog.Accepted: #if Ok buttom try again
           ret = self.dialog.pm100d.itemText(self.dialog.pm100d.currentIndex()) #new port
           self.PD.port = str(ret) 
           self.PD.flagWhile = False #change PD stop loop condition to try again
       else: #pressed cancel, so it gives up
           self.PD.photodetector.__del__() #delete objects
           self.PD.terminate() #stop thread
           self.PD.quit()
</code></pre>

<p>Now the PD class, which is in another thread but in the same file as gui:</p>

<pre><code>class PDThread(QtCore.QThread):

valueupdate = QtCore.pyqtSignal(float) #creating signals
dialogSignal = QtCore.pyqtSignal() #signal in case of error
state = 1 #used to stop thread

def __init__(self, state, port):
    QtCore.QThread.__init__(self)
    self.photodetector = PM100D() #creates the PD object
    self.port = port

def run(self):
    while True:
        self.flagWhile = True #used to leave while
        try:
            self.photodetector.connect(self.port) #try to connect
        except:
            self.dialogSignal.emit() #emit error signal
            while self.flagWhile == True:
                time.sleep(0.5) #wait here until user press something in the dialog, which is in another thread
        else:
            break #leave loop when connected

    window.PDState = 1 #change state of main gui buttom (change functionality to turn off if pressed again)
    window.startpd.setText('Stop PD')   #change buttom label
    while self.state == 1:
        time.sleep(0.016)
        value = self.photodetector.get_pow() #get PD pow
        self.valueupdate.emit(value) #emit it
</code></pre>

<p>The AlgoNanoMax file:</p>

<pre><code>import gui
from NanoMax import Nano

class NanoMax(gui.MyApp): #inheriting parent

def __init__(self, mcontroller_port):
    self.mcontroller = Nano(mcontroller_port) #mcontroller is the communication to the motor

def maximize_nano_x(self, step=0.001, spiral_number=3):
    ''' Alignment procedure with the nano motor X'''
    print 'Optimizing X'
    power = super(NanoMax, self).ReturnPow() #here I try to read from the photodetector
    xpos = self.mcontroller.initial_position_x
    position = []
    position = [[power, xpos]]
    xsign = 1
    self.mcontroller.move_relative(self.mcontroller.xaxis, (-1) * spiral_number * step)
    print 'X nano move: '+ str((-1) * spiral_number * step * 1000) + ' micrometers'
    time.sleep(4)
    power = super(NanoMax, self).ReturnPow()
    xpos += (-1) * spiral_number * step
    position.append([power, xpos])
    for _ in xrange(2*spiral_number):
        self.mcontroller.move_relative(self.mcontroller.xaxis, xsign * step)
        print 'X nano move: '+ str(xsign * step * 1000) + ' micrometers'
        time.sleep(5)
        power = super(NanoMax, self).ReturnPow()
        xpos += xsign * step
        position.append([power, xpos])
    pospower = [position[i][0] for i in xrange(len(position))]
    optimalpoint = pospower.index(max(pospower))
    x_shift = (-1) * (xpos - position[optimalpoint][1])
    print 'Maximum power: ' + str(max(pospower)) + ' dBm'
    print 'Current power: ' + str(super(NanoMax, self).ReturnPow()) + ' dBm'
    self.mcontroller.move_relative(self.mcontroller.xaxis, x_shift)
</code></pre>

<p>The <code>__init__</code> for <code>NanoMax</code> and <code>MyApp</code> should call <code>super().__init__()</code> to ensure initialization is done for all levels (if this is Python 2, you can't use no-arg <code>super</code>, so it would be <code>super(NanoMax, self).__init__()</code> and <code>super(MyApp, self).__init__()</code> respectively). This assumes the <code>PyQT</code> was properly written with new-style classes, and correct use of <code>super</code> itself; you're using <code>super</code> in other places, so presumably at least the former is true. Using <code>super</code> appropriately in all classes will ensure all levels are <code>__init__</code>-ed once, while manually listing super classes won't work in certain inheritance patterns, or might call some <code>__init__</code>s multiple times or not at all.</p>

<p>If there is a possibility that many levels might take arguments, you should also accept <code>*args</code>/<code>**kwargs</code> and forward them to the <code>super().__init__</code> call so the arguments are forwarded where then need to go.</p>

<p>Combining the two, your code should look like:</p>

<pre><code>class MyApp(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        super(MyApp, self).__init__(*args, **kwargs)
        ... rest of __init__ ...

class PDThread(QtCore.QThread):
    def __init__(self, state, port, *args, **kwargs):
        super(PDThread, self).__init__(*args, **kwargs)
        ...

class NanoMax(gui.MyApp): #inheriting parent

    def __init__(self, mcontroller_port, *args, **kwargs):
        super(NanoMax, self).__init__(*args, **kwargs)
        self.mcontroller = Nano(mcontroller_port) #mcontroller is the communication to the motor
</code></pre>

<p>Note: If you've overloaded methods that the super class might call in its <code>__init__</code> and your overloads depend on state set in your own <code>__init__</code>, you'll need to set up that state before, rather than after the <code>super().__init__(...)</code> call. Cooperative multiple inheritance can be a pain that way. Also note that using positional arguments for anything but the lowest level class can be ugly with multiple inheritance, so it may make sense to pass all arguments by keyword, and only accept and forward <code>**kwargs</code>, not <code>*args</code>, so people don't pass positional arguments in ways that break if the inheritance hierarchy changes slightly.</p>

python multithreading inheritance pyqt parent-child