子类化 threading.Thread 时出现 "RuntimeError: thread.__init__() 未调用
我需要创建和列表 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__()
: