2016-11-01 58 views
0

的一個子類時,我想提出它運行可使用CTRL +ç同時中斷兩個線程的程序。下面的腳本就是這樣一個簡化版本:「Asse田:螺紋.__的init __()不叫」初始化threading.Thread

import time 
import threading 

class Controller(object): 
    def __init__(self, name=None): 
     self.name = name 

    def run_once(self): 
     print("Controller {} is running once...".format(self.name)) 

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

if __name__ == "__main__": 
    controller1 = Controller(name="1") 
    controller2 = Controller(name="2") 
    thread1 = threading.Thread(target=controller1.run_forever) 
    thread2 = threading.Thread(target=controller2.run_forever) 
    thread1.daemon = True 
    thread2.daemon = True 
    thread1.start() 
    thread2.start() 


    try: 
     while True: 
      thread1.join(1) 
      thread2.join(1) 
      if not thread1.isAlive() or not thread2.isAlive(): 
       break 
    except KeyboardInterrupt: 
     pass 

我試圖使代碼更有點幹通過執行以下操作:

import time 
import threading 

class Controller(object): 
    def __init__(self, name=None): 
     self.name = name 

    def run_once(self): 
     print("Controller {} is running once...".format(self.name)) 

    def run_forever(self): 
     while True: 
      self.run_once() 
      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) 
     self.daemon = True 
     self.start() 


if __name__ == "__main__": 
    thread1 = ThreadController(name="1") 
    thread2 = ThreadController(name="2") 

    try: 
     while True: 
      thread1.join(1) 
      thread2.join(1) 
      if not thread1.isAlive() or not thread2.isAlive(): 
       break 
    except KeyboardInterrupt: 
     pass 

然而,當我嘗試運行後腳本,我得到以下錯誤:

Traceback (most recent call last): 
    File "threading_test3.py", line 34, in <module> 
    thread1 = ThreadController(name="1") 
    File "threading_test3.py", line 18, in __init__ 
    Controller.__init__(self, *args, **kwargs) 
    File "threading_test3.py", line 6, in __init__ 
    self.name = name 
    File "/usr/lib/python2.7/threading.py", line 971, in name 
    assert self.__initialized, "Thread.__init__() not called" 
AssertionError: Thread.__init__() not called 

我不明白爲什麼Thread.__init__()不叫,因爲它看起來像它被稱爲在的。什麼導致了這個錯誤?

+2

從'Controller'和'threading.Thread'的多重繼承是真正錯誤的方法。如果你想減少代碼重複,寫一個函數。 – user2357112

+2

根據[docs](https://docs.python.org/2/library/threading.html#thread-objects)如果子類重寫構造函數,它必須確保調用基類構造函數(Thread .__ init __())之前做任何其他線程.' – CAB

+0

...跟隨在@ CAB的答案:即,在這裏你初始化'線程'之前'Controller',這就是產生異常。儘管你的方法在概念上仍然不是正確的,正如user2357112所說的。 – spectras

回答

1

調用Thread的init,第一個;

class ThreadController(Controller, threading.Thread): 
    def __init__(self, *args, **kwargs): 
     threading.Thread.__init__(self, target=self.run_forever) 
     Controller.__init__(self, *args, **kwargs) 
     self.daemon = True 
     self.start()