我想运行一个代码,该代码每5秒运行一个带参数的函数(例如greet(h))。我尝试使用线程,但它不起作用。它只执行一次。请参阅下面的代码和错误:
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
请帮忙。
由于
答案 0 :(得分: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()
方法以允许线程在需要时终止。我还将print "%s" % hello
函数中的greeting()
简化为print hello
。
答案 1 :(得分:3)
您需要将参数oh_hi
作为参数本身传递给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()
答案 2 :(得分: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()
代码的问题是在构建greeting(oh_hi)
对象时会评估Timer
。该函数已执行但没有返回值,None
成为Timer
的第二个参数,当然抱怨None
不可调用。
答案 3 :(得分: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()