在Python中每隔X秒执行一个带参数的函数

4

我想运行一个带参数的函数(例如greet(h))并每5秒钟运行一次。 我尝试使用线程,但它不起作用。 它只执行一次。 请参见下面的代码和错误:

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个回答

4
正如其他人指出的那样,错误是因为您没有向 threading.Timer() 方法传递正确的参数。纠正后,将在 5 秒后运行您的函数一次。有多种方法可以使其重复执行。
一种 面向对象 的方法是派生一个新的 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" % helloprint hello

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
threading.Timer()仅运行一次。它不会在每个X时间段运行。 - HongboZhu

0
import time

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

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

如果你想使用 threading.Timer,请记住你必须以这种方式传递参数(参见文档):

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

你的代码问题在于 greeting(oh_hi) 在构建 Timer 对象时被评估。该函数被执行但没有返回值,None 成为 Timer 的第二个参数,当然会抱怨 None 不可调用。

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

需要一个函数作为第二个参数。你的代码给了它None(函数greeting(hello)的返回值)。你应该使用:

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

这忽略了oh_hi参数。

阅读文档建议:

threading.Timer(1, greeting, args=[oh_hi]).start()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接