跨不同线程使用类属性/方法 - Python

时间:2015-12-09 15:11:55

标签: python multithreading object attributeerror nonetype

我会尽力以明确的方式解释这个问题,它是我为A级项目开发的更大的软件的一部分 - 一个旨在创建一个简单版本的项目一个图形化的编程系统(想想猴子用大约7个命令做的划痕)。

我目前的麻烦源于需要在一个独特的线程上运行执行函数,该线程能够与用户界面交互,该用户界面显示执行用户(使用Tkinter库编写)执行代码块的结果主线程。此功能旨在通过一个动态列表,其中包含用户“代码”的信息,其形式可以循环并逐行处理。

执行开始时会出现问题,并且线程函数会尝试调用属于用户界面类的函数。我对多线程的理解有限,所以我很可能会破坏一些重要的规则并以无意义的方式做事,并且这里的帮助会很棒。

我已经接近了之前的功能,但总是会以不同的方式出现一些错误(主要是因为我原来尝试在第二个线程中打开一个tkinter窗口......一个坏主意)。

据我所知,我当前的代码在打开第二个线程方面工作,在主线程中打开UI,并开始在第二个线程中运行执行功能。为了解释这个问题,我创建了一小段代码,它们在相同的基础上工作,并产生相同的“无类型”错误,我会使用原始代码,但它很笨重,并且更加烦人比下面:

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()

运行此代码时,会产生以下结果:

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'

我想应该注意的是tkinter窗口按照我的意愿打开,并且线程类执行它应该做的事情,但似乎并不知道输出UI的存在。我认为这是由于对象定位和线程的某些部分,我可悲地了解不足。

那么,有没有一种方法可以从螺纹函数中调用输出ui中的函数?或者有类似的东西吗? 应该注意的是,我没有在主类的 init 函数中创建输出窗口,因为我需要能够创建输出窗口并启动线程等作为结果另一个输入。

对不起,如果这没有意义,请对我大喊,我会尝试修复它,但是非常感谢帮助,欢呼。

1 个答案:

答案 0 :(得分:0)

这里的问题是您的操作顺序。您在ThreadingClass中创建MainClass.beginExecute(),其中会调用self.start()。这会调用run,最终会尝试调​​用main.outputUI上的函数。但是main.outputUI尚未初始化(这是beginExecute()中的 next 行)。你可以通过重新排序这两行来使它工作。但是你可能不想在线程的self.start()中调用__init__。这似乎很糟糕。