在 Python 3 中安排重复事件
我正在尝试安排一个重复事件在 Python 3 中每分钟运行一次。
我已经看到了 sched.scheduler 类,但我想知道是否还有其他方法可以做到这一点。我听说我可以为此使用多个线程,我不介意这样做。
我基本上是请求一些 JSON,然后解析它;它的价值随着时间的推移而变化。
要使用 sched.scheduler,我必须创建一个循环来请求它安排事件运行一小时:
scheduler = sched.scheduler(time.time, time.sleep)
# Schedule the event. THIS IS UGLY!
for i in range(60):
scheduler.enter(3600 * i, 1, query_rate_limit, ())
scheduler.run()
还有哪些其他方法可以做到这一点?
I'm trying to schedule a repeating event to run every minute in Python 3.
I've seen class sched.scheduler
but I'm wondering if there's another way to do it. I've heard mentions I could use multiple threads for this, which I wouldn't mind doing.
I'm basically requesting some JSON and then parsing it; its value changes over time.
To use sched.scheduler
I have to create a loop to request it to schedule the even to run for one hour:
scheduler = sched.scheduler(time.time, time.sleep)
# Schedule the event. THIS IS UGLY!
for i in range(60):
scheduler.enter(3600 * i, 1, query_rate_limit, ())
scheduler.run()
What other ways to do this are there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
采用原始的 threading.Timer() 类实现并修复 run() 方法,我得到类似以下内容:
调用的 wait() 方法是使用条件变量,所以它应该相当有效。
Taking the original
threading.Timer()
class implementation and fixing therun()
method I get something like:The
wait()
method called is using a condition variable, so it should be rather efficient.不久前我遇到了类似的问题,所以我制作了一个 python 模块 event-scheduler 来解决这。它具有与 sched 库非常相似的 API,但有一些差异:
可以通过
pip install event-scheduler
安装I ran into a similar issue a while back so I made a python module event-scheduler to address this. It has a very similar API to the sched library with a few differences:
It can be installed by
pip install event-scheduler
我从 JavaScript 中找到了 setTimeout 和 setInterval 的模仿,但是是在 Python 中。
使用此类,您可以:
我知道它看起来很复杂,但我需要它拥有的所有功能,就像 JavaScript 中一样。请注意,您需要预先创建一个函数并使用函数名称作为参数(请参阅代码)。
希望这有帮助。
I figured out a mimic for setTimeout and setInterval from JavaScript, but in Python.
With this class you can:
I know it seems complex but I needed all the functionality it had just like in JavaScript. Note that you will need to pre-create a function and use the function name as a parameter (see code).
Hope this helps.
您可以使用
threading.Timer
,但这也会调度一次性事件,类似于调度程序对象的.enter
方法。将一次性调度程序转换为周期性调度程序的正常模式(在任何语言中)是让每个事件以指定的时间间隔重新调度自身。例如,对于
sched
,我不会像您一样使用循环,而是使用类似的东西:并通过调用启动整个“永久定期计划”
或者,我可以使用
threading.Timer
而不是scheduler.enter
,但模式非常相似。如果您需要更精细的变化(例如,在给定时间或在某些条件下停止定期重新安排),那么使用一些额外参数并不难。
You could use
threading.Timer
, but that also schedules a one-off event, similarly to the.enter
method of scheduler objects.The normal pattern (in any language) to transform a one-off scheduler into a periodic scheduler is to have each event re-schedule itself at the specified interval. For example, with
sched
, I would not use a loop like you're doing, but rather something like:and initiate the whole "forever periodic schedule" with a call
Or, I could use
threading.Timer
instead ofscheduler.enter
, but the pattern's quite similar.If you need a more refined variation (e.g., stop the periodic rescheduling at a given time or upon certain conditions), that's not too hard to accomodate with a few extra parameters.
您可以使用时间表。它适用于 Python 2.7 和 3.3,并且相当轻量级:
You could use schedule. It works on Python 2.7 and 3.3 and is rather lightweight:
我对这个主题的粗浅看法:
用法:
功能:
start()
和stop()
可以安全调用多次即使计时器已经启动/停止间隔
,它将在下次运行后生效。对于args
、kwargs
甚至function
也是如此!My humble take on the subject:
Usage:
Features:
start()
andstop()
are safe to call multiple times even if the timer has already started/stoppedinterval
anytime, it will be effective after next run. Same forargs
,kwargs
and evenfunction
!基于MestreLion的回答,它解决了多线程的一个小问题:
Based on MestreLion answer, it solve a little problem with multithreading:
您可以使用高级 Python 调度程序。它甚至有一个类似 cron 的界面。
You could use the Advanced Python Scheduler. It even has a cron-like interface.
使用 Celery。
Use Celery.
根据 Alex Martelli 的回答,我实现了更容易集成的装饰器版本。
Based on Alex Martelli's answer, I have implemented decorator version which is more easier to integrated.
文档:高级 Python 调度程序
可用字段:
Doc: Advanced Python Scheduler
Available fields:
这是一个使用
Thread
的快速而肮脏的非阻塞循环:没有什么特别的,
worker
会延迟创建一个自己的新线程。可能不是最有效的,但足够简单。如果您需要更复杂的解决方案,northtree 的答案将是您的最佳选择。基于这个,我们可以做同样的事情,只需使用
Timer
:Here's a quick and dirty non-blocking loop with
Thread
:There's nothing particularly special, the
worker
creates a new thread of itself with a delay. Might not be most efficient, but simple enough. northtree's answer would be the way to go if you need more sophisticated solution.And based on this, we can do the same, just with
Timer
:看我的样本
See my sample
有一个新包,名为
ischedule
。对于这种情况,解决方案可能如下:一切都在主线程上运行,并且 run_loop 内没有忙等待。启动时间非常精确,通常在指定时间的几分之一毫秒内。
There is a new package, called
ischedule
. For this case, the solution could be as following:Everything runs on the main thread and there is no busy waiting inside the run_loop. The startup time is very precise, usually within a fraction of a millisecond of the specified time.