我有一个类有两个方法run()
和run_forever()
,后者重复调用前者。我想在不同的线程上为类的不同实例运行run_forever()
,但到目前为止,我还没有能够偏离threading.Thread
调用run()
的默认行为1}}。
以下是我尝试实现的简化版本:
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...
一次,并且在target=self.run_forever
的初始化中设置threading.Thread
时,不会像我预期的那样每秒继续打印它。我如何修改此代码以实现所需的行为?
答案 0 :(得分:2)
停止继承Controller
:
controller = Controller()
thread = threading.Thread(target=controller.run_forever)
答案 1 :(得分:2)
您实际上是在覆盖线程的run
方法:您的ThreadController
继承自Controller
和Thread
,Controller
类实现它自己的run
。
来自docs:
标准run()方法调用传递给对象构造函数的可调用对象作为目标参数
但是您的run
没有调用任何内容(不对目标做任何事情)。它只打印运行一次... 您看到的print
单个Thread
试图执行其run()
方法。嗯...... 试图并且实际上取得了成功。的; - )强>
想到解决此问题的一些事情(虽然我个人可能会更改代码并尝试避免双重继承)会将Controller.run
的名称更改为像.do
:
class Controller(object):
def do(self):
print("Running once...")
def run_forever(self):
while True:
self.do()
time.sleep(1)
答案 2 :(得分: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
参数这一事实之外,我尊重这篇文章的标题:-)。
答案 3 :(得分:0)
我认为您希望Controller从Thread继承,然后不要覆盖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()