Using class attributes/methods across different threads - Python
Question: I'll do my best to explain this issue in a clear way, it's come up as part of
a much larger piece of software I'm developing for an A level project - a
project that aims to create a simple version of a graphical programming system
(think scratch made by monkeys with about 7 commands).

My trouble currently stems from the need to have an execution function running
on a unique thread that is capable of interacting with a user interface that
shows the results of executing the code blocks made by the user (written using
the Tkinter libraries) on the main thread. This function is designed to go
through a dynamic list that contains information on the user's "code" in a
form that can be looped through and dealt with "line by line".

The issue occurs when the execution begins, and the threaded function attempts
to call a function that is part of the user interface class. I have limited
understanding of multi threading, so it's all too likely that I am breaking
some important rules and doing things in ways that don't make sense, and help
here would be great.

I have achieved close to the functionality I am after previously, but always
with some errors coming up in different ways (mostly due to my original
attempts opening a tkinter window in a second thread... a bad idea).

As far as I'm aware my current code works in terms of opening a second thread,
opening the UI in the main thread, and beginning to run the execution function
in the second thread. In order to explain this issue, I have created a small
piece of code that works on the same basis, and produces the same "none type"
error, I would use the original code, but it's bulky, and a lot more annoying
to follow than below:

    
    
    from tkinter import *
    import threading
    
    #Represents what would be my main code
    class MainClass():
        #attributes for instances of each of the other classes
        outputUI = None
        threadingObject = None
    
        #attempt to open second thread and the output ui 
        def beginExecute(self):
            self.threadingObject = ThreadingClass()
            self.outputUI = OutputUI()
    
        #called by function of the threaded class, attempts to refer to instance
        #of "outputUI" created in the "begin execute" function
        def execute(self):
            return self.outputUI.functionThatReturns()
    
    #class for the output ui - just a blank box    
    class OutputUI():
    
        #constructor to make a window
        def __init__(self):
            root = Tk()
            root.title = ("Window in main thread")
            root.mainloop()
    
        #function to return a string when called
        def functionThatReturns(self):
            return("I'm a real object, look I exist! Maybe")
    
    #inherits from threading library, contains threading... (this is where my 
    #understanding gets more patchy) 
    class ThreadingClass(threading.Thread):
    
        #constructor - create new thread, run the thread...     
        def __init__(self):
            threading.Thread.__init__(self)
            self.start()
    
        #auto called by self.start() ^ (as far as I'm aware)
        def run(self):
            #attempt to run the main classes "execute" function
            print(mainClass.execute())
    
    #create instance of the main class, then attempt execution of some
    #threading    
    mainClass = MainClass()
    mainClass.beginExecute()
    

When this code is run, it produces the following result:

    
    
    Exception in thread Thread-1:
    Traceback (most recent call last):
      File "C:\Python34\lib\threading.py", line 920, in _bootstrap_inner
        self.run()
      File "H:/Programs/Python/more more threading tests.py", line 33, in run
        print(mainClass.execute())
      File "H:/Programs/Python/more more threading tests.py", line 14, in execute
        return self.outputUI.functionThatReturns()
    AttributeError: 'NoneType' object has no attribute 'functionThatReturns'
    

I guess it should be noted that the tkinter window opens as I hoped, and the
threading class does what it's supposed to, but does not appear to be aware of
the existence of the output UI. I assume this is due to some part of object
orientation and threading of which I am woefully under-informed.

So, is there a way in which I can call the function in the output ui from the
threaded function? Or is there a work around to something similar? It should
be noted that I didn't put the creation of the output window in the **init**
function of the main class, as I need to be able to create the output window
and start threading etc as a result of another input.

Sorry if this doesn't make sense, shout at me and I'll try and fix it, but
help would be greatly appreciated, cheers.


Answer: The problem here is your order of operations. You create a `ThreadingClass` in
`MainClass.beginExecute()`, which calls `self.start()`. That calls `run` which
ultimately tries to call a function on `main.outputUI`. But `main.outputUI`
hasn't been initialized yet (that's the _next_ line in `beginExecute()`). You
could probably make it work just by reordering those two lines. But you
probably don't want to be calling `self.start()` in the thread's `__init__`.
That seems like poor form.

