在python中每X秒执行一个函数(带参数)

时间:2011-04-06 09:13:30

标签: python

我想运行一个代码,该代码每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

请帮忙。

由于

4 个答案:

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