2011-04-06 303 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()