等效于python中的setInterval [英] Equivalent of setInterval in python
问题描述
我最近发布了一个问题,有关如何推迟在Python中执行函数(相当于Javascript setTimeout
),使用threading.Timer
确实是一个简单的任务(好吧,只要函数不与其他代码共享状态,这就很简单,但是在任何事件驱动的环境中都会产生问题) ).
I have recently posted a question about how to postpone execution of a function in Python (kind of equivalent to Javascript setTimeout
) and it turns out to be a simple task using threading.Timer
(well, simple as long as the function does not share state with other code, but that would create problems in any event-driven environment).
现在,我正在尝试做得更好,并模仿setInterval
.对于不熟悉Javascript的用户,setInterval
允许每x秒重复调用一次函数,而不会阻止其他代码的执行.我创建了这个示例装饰器:
Now I am trying to do better and emulate setInterval
. For those who are not familiar with Javascript, setInterval
allows to repeat a call to a function every x seconds, without blocking the execution of other code. I have created this example decorator:
import time, threading
def setInterval(interval, times = -1):
# This will be the actual decorator,
# with fixed interval and times parameter
def outer_wrap(function):
# This will be the function to be
# called
def wrap(*args, **kwargs):
# This is another function to be executed
# in a different thread to simulate setInterval
def inner_wrap():
i = 0
while i != times:
time.sleep(interval)
function(*args, **kwargs)
i += 1
threading.Timer(0, inner_wrap).start()
return wrap
return outer_wrap
将按以下方式使用
@setInterval(1, 3)
def foo(a):
print(a)
foo('bar')
# Will print 'bar' 3 times with 1 second delays
在我看来,它工作正常.我的问题是
and it seems to me it is working fine. My problem is that
- 它似乎过于复杂,我担心我可能错过了一个更简单/更好的机制
- 可以在没有第二个参数的情况下调用装饰器,在这种情况下它将永远持续下去.当我说到超越时,我的意思是永远-即使从主线程调用
sys.exit()
也不会停止它,也不会命中Ctrl+c
.阻止它的唯一方法是从外部杀死python进程.我希望能够从主线程发送一个将停止回调的信号.但是我是线程的初学者-如何在线程之间进行通信?
- it seems overly complicated, and I fear I may have missed a simpler/better mechanism
- the decorator can be called without the second parameter, in which case it will go on forever. When I say foreover, I mean forever - even calling
sys.exit()
from the main thread will not stop it, nor will hittingCtrl+c
. The only way to stop it is to kill python process from the outside. I would like to be able to send a signal from the main thread that would stop the callback. But I am a beginner with threads - how can I communicate between them?
编辑如果有人怀疑,这是装饰器的最终版本,这要感谢jd
EDIT In case anyone wonders, this is the final version of the decorator, thanks to the help of jd
import threading
def setInterval(interval, times = -1):
# This will be the actual decorator,
# with fixed interval and times parameter
def outer_wrap(function):
# This will be the function to be
# called
def wrap(*args, **kwargs):
stop = threading.Event()
# This is another function to be executed
# in a different thread to simulate setInterval
def inner_wrap():
i = 0
while i != times and not stop.isSet():
stop.wait(interval)
function(*args, **kwargs)
i += 1
t = threading.Timer(0, inner_wrap)
t.daemon = True
t.start()
return stop
return wrap
return outer_wrap
它可以与上述的固定重复次数一起使用
It can be used with a fixed amount of repetitions as above
@setInterval(1, 3)
def foo(a):
print(a)
foo('bar')
# Will print 'bar' 3 times with 1 second delays
或者可以一直运行直到收到停止信号
or can be left to run until it receives a stop signal
import time
@setInterval(1)
def foo(a):
print(a)
stopper = foo('bar')
time.sleep(5)
stopper.set()
# It will stop here, after printing 'bar' 5 times.
推荐答案
您的解决方案对我来说很好.
Your solution looks fine to me.
有几种与线程通信的方法.要命令一个线程停止,可以使用threading.Event()
,它具有一个可以使用的wait()
方法而不是time.sleep()
.
There are several ways to communicate with threads. To order a thread to stop, you can use threading.Event()
, which has a wait()
method that you can use instead of time.sleep()
.
stop_event = threading.Event()
...
stop_event.wait(1.)
if stop_event.isSet():
return
...
为使线程在程序终止时退出,请在调用start()
之前将其daemon
属性设置为True
.这也适用于Timer()
对象,因为它们是threading.Thread
的子类.请参见 http://docs.python.org/library/threading.html#threading.Thread.daemon
For your thread to exit when the program is terminated, set its daemon
attribute to True
before calling start()
. This applies to Timer()
objects as well because they subclass threading.Thread
. See http://docs.python.org/library/threading.html#threading.Thread.daemon
这篇关于等效于python中的setInterval的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!