"RuntimeError: thread.__ init __() не вызывается" при подклассе threading.Thread

Мне нужно запустить столько потоков класса Observer, сколько есть элементов в списке dirlist. Когда я запускаю консоль 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()

Но когда я пытаюсь сделать это из главного потока, который должен порождать потоки 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()

Ответы

Ответ 1

>>> master_thread.start()
RuntimeError: thread.__init__() not called

Обязательно вызовите Thread.__init__() в Master.__init__:

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

Ответ 2

Ну, я знаю, что поздно отвечать, но, черт возьми, я новичок в python, но со мной происходило то же самое, поэтому я вернулся, чтобы прочитать учебник по питону, и у него есть некоторые различия с тем, что мы оба пытаемся, Надеюсь, поможет. вместо этого

import threading

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

класс в соответствии с учебником по питону:

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 из родительского класса, он работает так, как предполагалось.

Ответ 3

Ошибка понятна, вы должны вызвать thread.__init__():

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