子类化 threading.Thread 时出现 "RuntimeError: thread.__init__() 未调用

24 投票
3 回答
37721 浏览
提问于 2025-04-17 02:26

我需要创建和列表 dirlist 中元素数量一样多的 Observer 类的线程。当我在 Python 控制台运行时,一切正常。

class Observer(Thread):
    def run(self):
        naptime = random.randint(1,10)
        print(self.name + ' starting, running for %ss.' % naptime)
        time.sleep(naptime)
        print(self.name + ' done')

observers = {}
for d in dirlist:
    observers[d] = Observer()
    observers[d].start()

但是当我尝试从一个主线程(Master 线程)去启动这些 Observer 线程时,就出现了错误。

class Master(Thread):
    def __init__(self, dirlist):
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            observers[d] = Observer()
            observers[d].start()
        while True:
            time.sleep(3600)

master_thread = Master(dirlist)
master_thread.start()

调用 Master.start 时出现了:

RuntimeError: thread.__init__() not called

这让我觉得很奇怪。
我无法理解这两种情况有什么不同。
有没有人能帮我找到解决我问题的方法?

奇怪的是,下面的代码没有产生错误,我也不明白为什么。

class Master(Thread):
    def set(self, dirlist):
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            observers[d] = Observer()
            observers[d].start()
        while True:
            time.sleep(3600)

master_thread = Master()
master_thread.set(dirlist)
master_thread.start()

3 个回答

6

错误很明显,你应该调用 thread.__init__()

def __init__(self, dirlist):
    super(Master, self).__init__()
    self.dirlist = dirlist       
16

我知道现在回答有点晚,但没关系,我也是个Python新手,之前也遇到过同样的问题。所以我回去看了一下Python的教程,发现我们尝试的方式有些不同,希望这能帮到你。

我们应该用这个:

import threading

class Master(Thread):
    def set(self, dirlist):
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            ...

根据Python教程,应该这样定义类:

class Master(threading.Thread):

这里缺少了一行:

threading.Thread.__init__(self)

所以最后应该是这样:

import threading

class Master(threading.Thread):
    def __init__(self, dirlist):
        threading.Thread.__init__(self)
        self.dirlist = dirlist
    def run(self):
        observers = {}
        for d in dirlist:
            ...

这样应该能正常工作,至少对我来说是这样。

希望这对你有帮助。

还有你第二次尝试使用set方法是有效的,因为你没有覆盖

__init__方法

来自Thread类,因此使用的是父类的原始init方法,这样它就能按预期运行了。

45
>>> master_thread.start()
RuntimeError: thread.__init__() not called
class Master(Thread):
    def __init__(self, dirlist):
        super(Master, self).__init__()
        self.dirlist = dirlist

确保在你的 Master.__init__ 方法里调用 Thread.__init__()

撰写回答