我如何在 Python 中获得类似 Cron 的调度程序?

新手上路,请多包涵

我正在寻找一个 Python 库,它将提供 atcron 类的功能。

我非常希望有一个纯 Python 解决方案,而不是依赖安装在盒子上的工具;这样我就可以在没有 cron 的机器上运行。

对于那些不熟悉 cron 的人:您可以根据如下表达式安排任务:

  0 2 * * 7 /usr/bin/run-backup # run the backups at 0200 on Every Sunday
 0 9-17/2 * * 1-5 /usr/bin/purge-temps # run the purge temps command, every 2 hours between 9am and 5pm on Mondays to Fridays.

cron 时间表达式语法不那么重要,但我想要具有这种灵活性的东西。

如果没有现成的东西可以为我做这件事,我将不胜感激地收到任何关于构建块来制作这样的东西的建议。

编辑 我对启动进程不感兴趣,只是“作业”也用 Python 编写 - python 函数。出于必要,我认为这将是一个不同的线程,但不会在不同的过程中。

为此,我正在寻找 cron 时间表达式的表现力,但在 Python 中。

Cron 已经 存在多年,但我正在努力使其尽可能便携。我不能依赖它的存在。

原文由 jamesh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 337
2 个回答

如果您正在寻找轻量级的结帐 时间表

 import schedule
import time

def job():
    print("I'm working...")

schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)

while 1:
    schedule.run_pending()
    time.sleep(1)

_披露_:我是那个图书馆的作者。

原文由 dbader 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以只使用普通的 Python 参数传递语法来指定您的 crontab。例如,假设我们定义一个 Event 类如下:

 from datetime import datetime, timedelta
import time

# Some utility classes / functions first
class AllMatch(set):
    """Universal set - match everything"""
    def __contains__(self, item): return True

allMatch = AllMatch()

def conv_to_set(obj):  # Allow single integer to be provided
    if isinstance(obj, (int,long)):
        return set([obj])  # Single item
    if not isinstance(obj, set):
        obj = set(obj)
    return obj

# The actual Event class
class Event(object):
    def __init__(self, action, min=allMatch, hour=allMatch,
                       day=allMatch, month=allMatch, dow=allMatch,
                       args=(), kwargs={}):
        self.mins = conv_to_set(min)
        self.hours= conv_to_set(hour)
        self.days = conv_to_set(day)
        self.months = conv_to_set(month)
        self.dow = conv_to_set(dow)
        self.action = action
        self.args = args
        self.kwargs = kwargs

    def matchtime(self, t):
        """Return True if this event should trigger at the specified datetime"""
        return ((t.minute     in self.mins) and
                (t.hour       in self.hours) and
                (t.day        in self.days) and
                (t.month      in self.months) and
                (t.weekday()  in self.dow))

    def check(self, t):
        if self.matchtime(t):
            self.action(*self.args, **self.kwargs)

(注:未彻底测试)

然后你的 CronTab 可以在正常的 python 语法中指定为:

 c = CronTab(
  Event(perform_backup, 0, 2, dow=6 ),
  Event(purge_temps, 0, range(9,18,2), dow=range(0,5))
)

通过这种方式,您可以获得 Python 参数机制的全部功能(混合位置和关键字参数,并且可以使用符号名称来表示周和月的名称)

CronTab 类将被定义为简单地以分钟为增量休眠,并在每个事件上调用 check()。 (虽然夏令时/时区可能有一些微妙之处需要警惕)。这是一个快速实现:

 class CronTab(object):
    def __init__(self, *events):
        self.events = events

    def run(self):
        t=datetime(*datetime.now().timetuple()[:5])
        while 1:
            for e in self.events:
                e.check(t)

            t += timedelta(minutes=1)
            while datetime.now() < t:
                time.sleep((t - datetime.now()).seconds)

需要注意的几点:Python 的工作日/月份是零索引的(与 cron 不同),并且该范围不包括最后一个元素,因此像“1-5”这样的语法变成范围(0,5) - 即 [0,1,2, 3,4]。如果您更喜欢 cron 语法,那么解析它应该不会太困难。

原文由 Brian 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题