我有一个类,它有两个方法run()
和run_forever()
,后者反复调用前者。我想在不同的线程上运行run_forever()
类的不同实例,但到目前为止,我还不能偏离threading.Thread
调用run()
的默认行为。
这是我想要实现的一个简化版本:
import time
import threading
class Controller(object):
def run(self):
print("Running once...")
def run_forever(self):
while True:
self.run()
time.sleep(1)
class ThreadController(Controller, threading.Thread):
def __init__(self, *args, **kwargs):
Controller.__init__(self, *args, **kwargs)
threading.Thread.__init__(self, target=self.run_forever)
if __name__ == "__main__":
thread_controller = ThreadController()
thread_controller.start()
thread_controller.join()
如果我运行这个脚本,它只打印一次Running once...
,而不是像我在threading.Thread
的初始化中设置target=self.run_forever
时那样每秒打印一次。如何修改此代码以实现所需的行为?
停止继承Controller
:
controller = Controller()
thread = threading.Thread(target=controller.run_forever)
您实际上覆盖了线程的run
方法:您的ThreadController
继承自Controller
和Thread
,并且Controller
类实现了自己的run
。
From the docs:
标准的run()方法调用作为目标参数传递给对象构造函数的可调用对象
但是你的run
没有调用任何东西(不做任何与目标)。它只打印一次Running…您看到的单个print
是试图执行其run()
方法的Thread
。嗯…尝试并实际上成功了。; -)
Controller.run
的名称更改为.do
:
class Controller(object):
def do(self):
print("Running once...")
def run_forever(self):
while True:
self.do()
time.sleep(1)
正如前面提到的,我也不喜欢多重继承,而是让带有run方法的类成为线程本身。这使得ThreadController
名副其实。我可以建议以下的重复代码:
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self, target=self.run_forever)
def do(self):
print("Running once...")
def run_forever(self):
while True:
self.do()
time.sleep(1)
class ThreadController(object):
def __init__(self, *args, **kwargs):
c = MyThread()
c.start()
c.join()
if __name__ == "__main__":
thread_controller = ThreadController()
当然,除了可以将run_forever
重命名为run
并省略构造函数的target
参数之外,但我尊重这篇文章的标题:-)。
我认为你想要控制器从线程继承,然后不要覆盖run
;
from threading import Thread
class Controller(Thread):
def __init__(self, *args, **kwargs):
super(Controller, self).__init__(*args, **kwargs)
def run_once(*args, **kwargs):
print("Running once...")
def run_forever(*args, **kwargs):
print("Running forever...")
运行一次;
Controller(target=Controller.run_once).start()
永远运行;
Controller(target=Controller.run_forever).start()