2011-04-06 686 views
4

我想運行一個代碼,每5秒運行一個帶有參數的函數(例如,greet(h))。我嘗試使用線程,但它不起作用。它只執行一次。請參閱下面的代碼和錯誤:如下圖所示在python中每隔X秒執行一個函數(帶參數)

import threading 

oh_hi = "Hi guys" 

def greeting(hello): 
    print "%s" % hello 



threading.Timer(1, greeting(oh_hi)).start() 

錯誤:

> >>> ================================ RESTART 
> ================================ 
> >>> Hi guys 
> >>> Exception in thread Thread-1: Traceback (most recent call last): 
> File "C:\Python27\lib\threading.py", 
> line 530, in __bootstrap_inner 
>  self.run() File "C:\Python27\lib\threading.py", line 
> 734, in run 
>  self.function(*self.args, **self.kwargs) TypeError: 'NoneType' object is not callable 

敬請協助。

感謝

回答

4

正如其他已經指出,這個錯誤是因爲你沒有將適當的參數傳遞給threading.Timer()方法。糾正這個錯誤將運行你的函數,一次,5秒後。有很多方法讓它重複。

object-oriented方法將導出一個新的threading.Thread子類。雖然可以創建一個明確實現所需內容的程序 - 即print "%s" % hello,但創建一個更通用的參數化子類只會稍微困難一些,它將在實例化過程中調用傳遞給它的函數(就像threading.Timer()一樣) 。這如下所示:

import threading 
import time 

class RepeatEvery(threading.Thread): 
    def __init__(self, interval, func, *args, **kwargs): 
     threading.Thread.__init__(self) 
     self.interval = interval # seconds between calls 
     self.func = func   # function to call 
     self.args = args   # optional positional argument(s) for call 
     self.kwargs = kwargs  # optional keyword argument(s) for call 
     self.runable = True 
    def run(self): 
     while self.runable: 
      self.func(*self.args, **self.kwargs) 
      time.sleep(self.interval) 
    def stop(self): 
     self.runable = False 

def greeting(hello): 
    print hello 

thread = RepeatEvery(3, greeting, "Hi guys") 
print "starting" 
thread.start() 
thread.join(21) # allow thread to execute a while... 
thread.stop() 
print 'stopped' 

輸出:

# starting 
# Hi guys 
# Hi guys 
# Hi guys 
# Hi guys 
# Hi guys 
# Hi guys 
# Hi guys 
# stopped 

除了重寫基threading.Thread類的__init__()run()方法,加入stop()方法,以允許在需要時被終止該線程。我還將greeting()函數中的print "%s" % hello簡化爲print hello

3

您需要的參數oh_hi傳遞作爲paramater本身threading.Timer ......如文檔中說明...

threading.Timer(interval, function, args=[], kwargs={})

要解決它,你會做。 ..

import threading 

def greeting(hello): 
    print "%s" % hello 

if __name__ == "__main__": 
    oh_hi = "Hi guys" 
    threading.Timer(1, greeting, args=(oh_hi,)).start() 
+1

threading.Timer()只運行一次。它不運行每個X時隙。 – HongboZhu 2014-02-13 15:40:37

0
import time 

def greeting(hello): 
    print "%s" % hello 

while True: 
    greeting(oh_hi) 
    time.sleep(5) 

如果你想使用threading.Timer,記住,你必須傳遞參數以這種方式(見the docs):

threading.Timer(1, greeting, (oh_hi,)).start() 

與您的代碼的問題是Timer對象正在修建時greeting(oh_hi)評估。該函數被執行但沒有返回值,並且None成爲Timer的第二個參數,那當然抱怨None不可調用。

0
threading.Timer(1, greeting(oh_hi)).start() 

需要一個函數作爲第二個參數。您的代碼給它None(功能greeting(hello)的返回值,你應該使用:。

threading.Timer(1, greeting).start() 

然而這忽略了oh_hi參數

documentation提示:

threading.Timer(1, greeting, args=[oh_hi]).start() 
相關問題