2016-11-01 3 views
1

私は2つのメソッドrun()run_forever()を持っています。後者は前者を繰り返し呼び出します。別のスレッドでクラスのインスタンスごとにrun_forever()を実行したいと思いますが、これまでのところ、threading.Threadのデフォルトの動作であるrun()を逸脱することはできませんでした。ここでthreading.Threadのstart()メソッドは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...を印刷し、私はにより意図のようにそれを毎秒を印刷し続けませんtarget=self.run_foreverthreading.Threadの初期化に設定します。どのように私はこのコードを変更して、望ましい動作を達成することができますか? Controllerから継承

+0

なぜあなたは 'run_forever'を持っていますか?ループを 'run'に入れることはできませんか? – Gabriel

+0

.start()を使ってみてください。 –

+1

Controller APIをThread APIにミックスしようとしていますが、メソッド名が衝突するため、動作しません。コントローラを変更できない場合は、コントローラを含むスレッドオブジェクトを解決する必要があります。簡単な方法は 'threading.Thread(target = Controll()。run_forever)'です。 – tdelaney

答えて

2

停止:

controller = Controller() 
thread = threading.Thread(target=controller.run_forever) 
2

あなたは事実上のスレッドのrun方法上書きされます:ControllerからとThreadからあなたのThreadController継承し、かつControllerクラスは、独自のrunを実装します。 docsから

標準run()メソッドは、ターゲット引数

としてオブジェクトのコンストラクタに渡された呼び出し可能オブジェクトを呼び出します。しかし、あなたのrunは(何もしない起動されていませんターゲット)で何でもしてください。 一度だけ実行しています...そのprintは、run()メソッドを実行しようとしているThreadです。まあ... に行って、実際に成功しています。 (私は個人的には、おそらくいくつかのより多くのコードを変更し、二重の継承を回避しようが).doのようなものに自分のController.runの名前を変更することになる頭に浮かぶ;-)

何かがこれを修正するには:

class Controller(object): 
    def do(self): 
     print("Running once...") 

    def run_forever(self): 
     while True: 
      self.do() 
      time.sleep(1) 
1

言われたように、私は多重継承も好きではありませんが、runメソッドを持つクラスをスレッド自体にしてください。それは実際にその名前が示唆するものをThreadControllerにします。もちろん、離れて1がrunrun_foreverの名前を変更し、コンストラクタにtarget引数を省略しますが、私はこのポスト:-)のタイトルを尊重することができたという事実からその

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() 

:私は、次のrefracturedのコードを示唆しています。

0

私はあなたがControllerからスレッドを継承してから、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...") 

1回実行します。

Controller(target=Controller.run_once).start() 

永遠に実行します。

Controller(target=Controller.run_forever).start() 
関連する問題