在本 Python APScheduler 教程中,我们将探索 APScheduler 库,也称为高级 Python 调度程序。顾名思义,这是 Python 中可用的最先进的调度程序库之一,具有各种不同的功能和调度选项。
由于APScheduler不包含在Python标准库中,因此需要单独下载。您可以使用 pip 执行此操作。
pip install apscheduler
如果您对作为标准库一部分的计划库感兴趣,请查看此库。
有 4 个主要组件组成了 Python APScheduler 库。
触发器 – 负责计划逻辑,并决定何时执行作业。
作业存储 – 顾名思义,这定义了存储所有计划作业的区域。默认存储只是将所有作业存储在内存中。但对于更专业的用例,您可以将它们存储在数据库(如 SQL)中。
执行程序 – 处理作业的运行。
调度程序 – 将所有内容绑定在一起的主干。每个应用程序通常只有一个调度程序。
本教程的目的不是涵盖所有这些方面,而是让您很好地掌握 Python APScheduler 库的基础知识并演示几个用例。
让我们来看看APScheduler中可用的各种类型的调度程序。
BlockingScheduler:当调度程序是进程中唯一运行的内容时使用。(在前景中运行)
BackgroundScheduler:在不使用以下任何框架,并希望调度程序在应用程序内部的后台运行时使用。(在单独的线程上运行)
AsyncIOScheduler:如果您的应用程序使用 asyncio 模块,则使用
GeventScheduler:如果您的应用程序使用 gevent,则使用
TornadoScheduler:如果您正在构建龙卷风应用程序,请使用
TwistedScheduler:在构建扭曲应用程序时使用
QtScheduler:在构建Qt应用程序时使用
其中大多数旨在与框架一起使用,因此如果您不使用任何框架,则可以忽略其中的大多数。对于常规用例,BackgroundScheduler 是一个不错的选择。我们将在大部分 Python APScheduler 教程中使用它。
计划作业时,需要为其选择触发器。触发器确定用于计算计划执行作业的日期/时间的逻辑。
Python APScheduler 库附带三种内置触发器类型供您选择:
date:当您只想在特定时间运行一次作业时使用。
interval:在要以固定的时间间隔运行作业时使用。
cron:当您希望在一天中的特定时间定期运行作业时。
了解其中每一种的用法非常重要。因此,我们将在本Python APScheduler教程中演示其中每一个的用法。(不要担心现在了解如何使用它们)
让我们看一下如何将作业添加到我们的调度程序。请记住,“作业”是我们分配给调度程序的任务,例如执行特定功能。
在做任何事情之前,我们需要设置一个调度程序。我们没有使用任何特殊的框架,只是想启动并运行一个简单的调度程序。(这对于大多数用例来说绰绰有余)。
1 2 3 4 | fromapscheduler.schedulers.background importBackgroundScheduler
# Creates a default Background Scheduler sched =BackgroundScheduler() |
此调度程序使用默认作业存储(基于内存)和最大线程计数 10。
将作业添加到调度程序的最常见方法是通过使用函数。此函数还返回一个 Job 对象,该对象可在以后的进一步处理中使用。(例如修改作业或从调度程序中删除作业)add_job()
以下代码每 5 秒执行一次该函数。prompt()
1 2 3 4 | defprompt(): print("Executing Task...")
sched.add_job(prompt, 'interval', seconds =5) |
.如您所见,我们传递了要调用的函数的名称。第二个参数指定触发器。此之后的参数定义调度逻辑。有许多参数,如秒、分钟、小时、日、周、月和年。add_job()
上述示例的完整代码如下所示。您会注意到,我们在此代码的末尾使用了一个无限循环。我们将在下一节中对此进行详细说明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | fromtime importsleep fromapscheduler.schedulers.background importBackgroundScheduler
# Creates a default Background Scheduler sched =BackgroundScheduler()
defprompt(): print("Executing Task...")
sched.add_job(prompt,'interval', seconds=5)
# Starts the Scheduled jobs sched.start()
# Runs an infinite loop whileTrue: sleep(1) |
尝试运行代码以亲自查看输出!
让我们快速看一下后台和阻塞调度程序之间的区别。顾名思义,后台调度程序运行与主线程不同的线程。主线程完成执行后,运行后台计划程序的线程也会关闭。即使有一些计划作业要执行,也会发生这种情况。
1 2 3 4 5 6 7 8 9 10 | fromapscheduler.schedulers.background importBackgroundScheduler
# Creates a default Background Scheduler sched =BackgroundScheduler()
defprompt(): print("Executing Task...")
sched.add_job(prompt,'interval', seconds=5) sched.start() |
如果你运行上面的代码(没有无限循环),你会注意到没有输出。这是因为主线程在调用函数后完成了执行。start()
这就是为什么在前面的示例中,我们使用无限循环来防止主线程关闭。
但是,使用阻塞调度程序,调度程序在主线程上运行。因此,直到调度程序使用该函数在主线程上停止之前,主线程不会关闭。shutdown()
下面的示例中的代码使用 BlockingScheduler 而不是 BackgroundScheduler。运行代码,并注意它将如何继续运行,即使没有无限循环。
1 2 3 4 5 6 7 8 9 10 11 12 | fromtime importsleep fromapscheduler.schedulers.background importBlockingScheduler
# Creates a default Background Scheduler sched =BlockingScheduler()
defprompt(): print("Executing Task...")
sched.add_job(prompt,'interval', seconds=5)
sched.start() |
有兴趣探索 Python 中的其他调度库吗?看看这个轻量级的 Python 调度替代方案!
现在让我们看一下 和 触发器的示例。datecron
日期触发器用于在特定时间点执行作业。此类作业仅运行一次。
下面的代码展示了这样一个示例。还可以将参数传递给使用该参数调用的函数。这是所有三个触发器中常见的,而不仅仅是 .argsdate
下面的代码使用了触发器。我们提供了三种不同的方法,您可以通过这些方式为参数选择值。daterun_date
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | fromtime importsleep fromdatetime importdate, datetime fromapscheduler.schedulers.background importBlockingScheduler
# Creates a default Background Scheduler sched =BlockingScheduler()
defjob(text): print(text)
# In 2022-4-30 Run once job Method sched.add_job(job, 'date', run_date =date(2019, 8, 30), args=['Job 1'])
# In 2022-4-30 12:00:00 Run once job Method sched.add_job(job, 'date', run_date =datetime(2022, 4, 30, 12, 0, 0), args=['Job 2'])
# In 2022-4-30 08:00:00 Run once job Method sched.add_job(job, 'date', run_date ='2022-4-30 08:00:00', args=['Job 2'])
sched.start() |
现在让我们看一下触发器。这是一种非常流行(且功能强大)的触发器类型,用于定期计划任务。例如,在每天的特定时间执行任务,或让任务在特定日期(如星期一到星期五)执行。cron
让我们看一下 5 个不同的示例,每个示例都展示了使用 APScheduler 调度 cron 作业的不同方式。
1 2 3 | # Runs every minute at 17 o'clock a day job Method sched.add_job(job, 'cron', hour=17, minute='*', args=['job 1']) |
上面的代码使用特殊字符“*”。这将导致作业每分钟重复一次。如果将“*”放在 seconds 参数中,它将每秒重复一次。
1 2 3 | # Runs every 5 minutes at 17 o'clock a day sched.add_job(job, 'cron', hour=17, minute='*/5', args=['job 2']) |
上面的代码是第一个代码的变体,但使用了格式。这会导致作业每“n”次重复一次。*/n
1 2 3 | # Runs once a day at 17:25 and 18:25 job Method sched.add_job(job, 'cron', hour='17-18', minute='25', args=['job 3']) |
此代码演示如何指定值范围。因此,允许我们让代码在 2 小时内执行,而不仅仅是一个小时。
1 2 3 4 5 | # Schedules job to be run on the third occurrence of Friday # on the months June, July, August, November and December # at 00:00, 01:00, 02:00, 03:00 and 04:00 sched.add_job(job, 'cron', month='6-8,11-12', day='3rd fri', hour='0-4', args=['job 4']) |
此代码演示了两个新内容。首先,它显示您可以指定多个范围,只需在它们之间添加逗号即可。其次,它显示了格式的使用,该格式导致作业在一个月内工作日的 -th 出现时运行。xth yxy
您可以使用另一个选项,称为 。单独使用会导致代码在当月的最后一天运行,否则会将作业安排在当月的最后一个星期五。lastlastlast fri
1 2 3 4 | # Runs from Monday to Friday at 6:30AM until 2022-06-30 00:00:00 sched.add_job(job, 'cron', day_of_week='mon-fri', hour=6, minute=30, end_date='2022-06-30', args=['job 5']) |
上面的代码主要展示了这样一个事实,即一旦到达某个日期,您就可以使用该选项停止执行代码。end_date
如果您想了解有关APScheduler中的Cron Trigger的更多信息,请查看我们的Cron专用教程,其中更详细地介绍了它。
与添加作业时可用选项的复杂性和数量相比,删除作业要容易得多。您只需要作业对象或我们在创建作业时分配的作业 ID。
早些时候,我们没有费心从任何地方存储返回的作业对象。但是,如果我们想以后删除作业,我们将不得不这样做。add_job()
1 2 | jobObj =sched.add_job(myfunc, 'interval', minutes=2) jobObj.remove() |
或者,您可以只分配一个 ID,以后可以使用该 ID 将其删除。
1 2 | sched.add_job(task, 'interval', minutes=2, id='random_job_id') sched.remove_job('random_job_id') |
请记住,使用完调度程序后,可以使用该功能将其关闭。shutdown()
1 | scheduler.shutdown() |
这标志着Python APScheduler教程的结束。非常欢迎对CodersLegacy的任何建议或贡献。有关教程内容的问题可以在下面的评论部分提出。