Python调度器设计:schedule类的代码分析

本文详细分析了Python定时调度库schedule的设计原理,重点介绍了Scheduler类和Job类的关键逻辑。通过建造者模式,schedule模块允许灵活地指定调度周期、起始weekday、时间以及随机调度时刻。文章还提供了一个自定义测试demo,帮助读者更好地理解和应用该库。
摘要由CSDN通过智能技术生成

schedule 是一个广泛使用的 python 定时调度框架,直接上代码。

代码解析

import schedule
import time

def do_task(time_str=time.time()):
    print('task run: %s' % time_str)

# 每 10 分钟执行一次任务
schedule.every(10).minutes.do(do_task)
# 每隔 5 到 10 分钟之间的任意一个时间执行一次任务
schedule.every(5).to(10).days.do(do_task)
# 每 1 小时执行一次任务
schedule.every().hour.do(do_task, time_str='1519351479.19554')
# 每天 10:30 执行一次任务
schedule.every().day.at("10:30").do(do_task)

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

schedule 模块的整体设计, 是把任务的自我管理部分做的很详细, 而把上层的调度做的很轻很薄, 关键逻辑点采用回调的方式, 依赖任务的自我管理去实现。

Scheduler 类的实例中, 维护了一个列表: jobs, 专门存储注册进来的任务快照:

Class Scheduler(object):
    def __init__(self):
        self.jobs = []

Scheduler 类最重要的方法是 run_pending(self), 其主要逻辑是遍历 jobs 列表中的所有 job, 从中找出当前时间点需要调度的 job, 并执行。这其中最重要的逻辑是判断一个 job 当前时间点是否需要被调度, 而这个过程是一个回调, 具体的逻辑则封装在 job.should_run 方法里。

def run_pending(self):
    _jobs = (job for job in self.jobs if job.should_run)
    for job in sorted(runnable_jobs):
        self._run_job(job)

值得注意的是, schedule 模块中并没有专门的逻辑去定时执行 run_pending 方法, 要想让定时调度持续跑起来, 需要自己实现:

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

相比 sched 模块的 ‘伪递归’ 而言, 这样的设计算是比较人性化的了, 可以认为它基本实现了真正意义上的定时调度。 schedule 模块实现了非常详细的任务自我管理逻辑:

class Job(object):
    def __init__(self, interval, scheduler=None):
        self.interval = interval  # pause interval * unit between runs
        self.latest = None  # upper limit to the interval
        self.job_func = None  # the job job_func to run
        self.unit = None  # time units, e.g. 'minutes', 'hours', ...
        self.at_time = None  # optional time at which this job runs
        self.last_run = None  # datetime of the last run
        self.next_run = None  # datetime of the next run
        self.period = None  # timedelta between runs, only valid for
        self.start_day = None  # Specific day of the week to start on
        self.tags = set()  # unique set of tags for the j
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值