【Python】APScheduler:Python中强大的任务调度库


我听见有人猜
你是敌人潜伏的内线
和你相知多年
我确信对你的了解
你舍命救我画面
一一在眼前浮现
司空见惯了鲜血
你忘记你本是娇娆的红颜
感觉你我彼此都那么依恋
                     🎵 许嵩《内线》


在 Python 开发中,定时任务是非常常见的需求,例如定期备份数据库、定时发送邮件提醒,或按固定时间抓取数据。如果你需要一个功能强大、灵活的调度库,APScheduler(Advanced Python Scheduler)是一个非常好的选择。

APScheduler 不仅支持简单的定时任务,还支持复杂的调度需求。它能够基于日期、固定时间间隔、或 cron 表达式调度任务,并且可以与多种后端存储系统(如数据库、Redis)集成,实现任务的持久化管理。

1. 什么是 APScheduler?

APScheduler 是一个功能强大的 Python 任务调度库。它支持以下几种任务调度方式:

基于时间间隔:每隔固定的时间执行任务。
基于日期:在特定的日期和时间点执行任务。
基于 cron 表达式:类似于 Linux 系统中的 cron 作业,可以非常灵活地指定复杂的时间调度。
持久化:支持任务存储到数据库中,重启后可以恢复任务。
APScheduler 还支持多种调度器,包括阻塞调度器(适合单线程的应用)、后台调度器(适合 Web 框架或多线程环境)、以及基于 Tornado、Twisted 等异步框架的调度器。

2. 安装 APScheduler

你可以通过 pip 来安装 APScheduler:

pip install apscheduler

安装完成后,你就可以开始在 Python 项目中使用 APScheduler 来调度任务。

3. 基本使用

APScheduler 使用起来非常灵活,常见的调度器是 BlockingScheduler 和 BackgroundScheduler。BlockingScheduler 通常用于简单脚本,它会阻塞主线程直到任务调度结束。而 BackgroundScheduler 可以在后台运行,适合与其他程序逻辑同时工作。

3.1 简单示例

下面是一个简单的任务调度示例,使用 BlockingScheduler 每隔 5 秒执行一次任务:

from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetimedef job():print(f"任务执行时间:{datetime.now()}")scheduler = BlockingScheduler()# 每 5 秒执行一次
scheduler.add_job(job, 'interval', seconds=5)# 启动调度器
scheduler.start()

在这个例子中,调度器会每隔 5 秒执行一次 job() 函数。scheduler.add_job() 方法用于添加一个任务,第一个参数是任务函数,第二个参数是调度方式(此处为 ‘interval’,表示基于时间间隔的调度),后面的 seconds=5 表示时间间隔为 5 秒。

3.2 使用 BackgroundScheduler

如果你不想让调度器阻塞主线程,使用 BackgroundScheduler 可能更合适。BackgroundScheduler 可以在后台运行,适用于与其他程序逻辑并行运行的场景。

from apscheduler.schedulers.background import BackgroundScheduler
import timedef job():print(f"任务执行中...")scheduler = BackgroundScheduler()
scheduler.add_job(job, 'interval', seconds=5)# 启动调度器
scheduler.start()# 主程序继续执行
while True:print("主程序运行中...")time.sleep(3)

在这个例子中,BackgroundScheduler 启动后,主程序会继续运行,同时后台任务每 5 秒执行一次。

4. 基于不同触发器的调度

APScheduler 具有多种任务触发器,可以灵活地根据时间进行任务调度。常见的触发器有三种:

DateTrigger:在特定的日期时间执行任务。
IntervalTrigger:每隔固定的时间间隔执行任务。
CronTrigger:使用类似 cron 表达式的方式进行调度。

4.1 基于日期的调度(DateTrigger)

如果你需要在特定的时间点执行任务,可以使用 DateTrigger:

from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime, timedeltadef job():print("一次性任务执行")scheduler = BlockingScheduler()# 设置任务在 5 秒后执行一次
run_time = datetime.now() + timedelta(seconds=5)
scheduler.add_job(job, 'date', run_date=run_time)scheduler.start()

在这个示例中,任务将在当前时间 5 秒后执行一次。

4.2 基于时间间隔的调度(IntervalTrigger)

间隔调度是 APScheduler 中最常用的调度方式之一。它允许你按照指定的时间间隔执行任务,例如每隔几秒、几分钟、几小时等。

scheduler.add_job(job, 'interval', minutes=10)  # 每 10 分钟执行一次
4.3 使用 Cron 表达式进行调度(CronTrigger)

CronTrigger 提供了最灵活的调度方式,类似于 Linux 系统中的 cron 作业。它允许你设置复杂的时间规则,如每周一上午 10:00 执行任务。

from apscheduler.schedulers.blocking import BlockingSchedulerdef job():print("每周任务执行")scheduler = BlockingScheduler()# 每周一上午 10 点执行
scheduler.add_job(job, 'cron', day_of_week='mon', hour=10, minute=0)scheduler.start()

这个例子展示了如何使用 cron 表达式来调度任务,它将在每周一上午 10:00 执行。

5. 任务的持久化

APScheduler 允许将任务存储在数据库等持久化存储中,使得任务可以在程序重启后继续执行。你可以选择 SQLite、MySQL、PostgreSQL 等数据库作为存储后端。

持久化调度任务的步骤大致如下:

安装数据库驱动,如 sqlite 或 mysqlclient。
配置 APScheduler 使用 SQLAlchemyJobStore 来管理任务。
下面是一个使用 SQLite 的例子:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore# 创建一个持久化存储(SQLite)
jobstores = {'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}scheduler = BackgroundScheduler(jobstores=jobstores)def job():print("任务执行中...")# 每 10 秒执行一次任务
scheduler.add_job(job, 'interval', seconds=10)scheduler.start()

在这个例子中,任务存储在 jobs.sqlite 数据库中,重启程序后,APScheduler 会从数据库中恢复任务。

6. 任务的暂停、恢复与删除

APScheduler 还支持对任务进行动态管理,如暂停、恢复和删除任务。你可以通过任务的 ID 来操作任务:

# 添加任务并指定任务 ID
scheduler.add_job(job, 'interval', seconds=10, id='my_job')# 暂停任务
scheduler.pause_job('my_job')# 恢复任务
scheduler.resume_job('my_job')# 删除任务
scheduler.remove_job('my_job')

7. 完整示例

下面是一个 APScheduler 的完整示例,展示了如何使用 BackgroundScheduler 进行定时任务调度,并将任务持久化到 SQLite 数据库中:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from datetime import datetime# 使用 SQLite 作为持久化存储
jobstores = {'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}scheduler = BackgroundScheduler(jobstores=jobstores)def send_email():print(f"发送提醒邮件,当前时间:{datetime.now()}")def backup_database():print(f"备份数据库,当前时间:{datetime.now()}")# 每天上午 8 点发送提醒邮件
scheduler.add_job(send_email, 'cron', hour=8, minute=0, id='email_job')# 每周日晚上 10 点备份数据库
scheduler.add_job(backup_database, 'cron', day_of_week='sun', hour=22, id='backup_job')scheduler.start()while True:pass  # 模拟程序一直运行

8. 总结

APScheduler 是一个强大且灵活的 Python 调度库,适用于从简单到复杂的定时任务场景。通过丰富的触发器支持(如基于日期、时间间隔、cron 表达式),以及与数据库等持久化存储的集成,APScheduler 能够满足各种调度需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/52003.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI学习记录 - transformers 的 linear 词映射层的详细分析, CrossEntropyLoss 函数解析

创作不易,有用的话点个赞。。。。。。 1. 假设条件 词汇表:假设词汇表包含四个词汇:[token_0, token_1, token_2, token_3]。 模型的输出概率分布:模型的输出经过 Softmax 转换后,得到概率分布:[0.1,0.5,…

88.SAPUI5 Model Binding的问题-在view更改数据,model却不变

目录 1.背景 2.sap.ui.model.BindingMode sap.ui.model.BindingMode.OneWay sap.ui.model.BindingMode.TwoWay 3.oModel.setDefaultBindingMode 方法说明 execOneWay方法 execTwoWay方法 1.背景 在做一个UI5项目,后台读取sap.ui.model.Model后,把…

qt-12工具盒(ToolBox)

工具盒--ToolBox drawer.hdrawer.cppmain.cpp运行图 drawer.h #ifndef DRAWER_H #define DRAWER_H #include <QWidget> #include <QToolBox> #include <QToolButton> #include <QGroupBox> #include <QVBoxLayout>class Drawer : public QToolB…

MiniCPM-V: A GPT-4V Level MLLM on Your Phone论文阅读

大模型的趋势&#xff1a;模型性能越来越好&#xff0c;模型参数变小&#xff0c;端边设备计算能力变强。 MiniCPM-V优点 结果好、OCR能力突出、多分辨率、多语言、易于部署 模型结构 图片encoder适用vit。输入整体以及切片。切片使用自适应算法&#xff0c;通过计算分数&am…

[LitCTF 2024]浏览器也能套娃?

题目有标志SSRF SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下&#xff0c;SSRF攻击的目标是从外网无法访问的内部系统。&#xff08;正是因为它是由服务端发起的&#xff0c;所以它能够请求到与它相…

数据结构----栈

一丶概念 只能在一端进行插入和删除操作的线性表&#xff08;又称为堆栈&#xff09;&#xff0c;进行插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底 二丶特点 先进后出 FILO first in last out 后进先出 LIFO last in first out 三丶顺序栈 逻辑结构&…

【网络】套接字(socket)编程——TCP版

接着上一篇文章&#xff1a;http://t.csdnimg.cn/GZDlI 在上一篇文章中&#xff0c;我们实现的是UDP协议的&#xff0c;今天我们就要来实现一下TCP版本的 接下来接下来实现一批基于 TCP 协议的网络程序&#xff0c;本节只介绍基于IPv4的socket网络编程 基于 TCP 的网络编程开…

给既有exe程序添加一机一码验证

原文地址&#xff1a;李浩的博客 lihaohello.top 本科期间开发过一款混凝土基本构件设计程序&#xff0c;该程序是一个独立的exe可执行文件&#xff0c;采用VC静态链接MFC库编制而成。近期&#xff0c;需要为该程序添加用户注册验证的功能&#xff0c;从而避免任何用户获取该程…

python从入门到精通:函数

目录 1、函数介绍 2、函数的定义 3、函数的传入参数 4、函数的返回值 5、函数说明文档 6、函数的嵌套调用 7、变量的作用域 1、函数介绍 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现特定功能的代码段。 name "zhangsan"; length len(nam…

Java八股整合(MySQL+Redis+Maven)

MySQL 数据库设计三范式 不可再分&#xff0c;部分依赖&#xff0c;传递依赖 主键和外键区别 主键非空约束&#xff0c;唯一性约束&#xff0c;唯一标识一个字段 外键用于和其他表建立连接&#xff0c;是另一张表的主键&#xff0c;可重复可为空可以有多个 为什么不推荐使…

链表---数据结构-黑马

链表 定义 链表是数据元素的线性集合&#xff0c;其每个元素都指向下一个元素&#xff0c;元素存储上是不连续的。 分类 单向链表&#xff0c;每个元素只知道自己的下一个元素是谁。 双向链表&#xff0c;每个元素知道自己的上一个元素和下一个元素。 循环链表&#xff0c;…

10W数据导入该如何与库中数据去重?

使用的是PostgreSQL 在做大数据量&#xff08;十万级&#xff09;导入时&#xff0c;某些字段和数据库表里数据&#xff08;千万级&#xff09;重复的需要排除掉&#xff0c;把表数据查询出来用程序的方式判断去重效率很低&#xff0c;于是考虑用临时表。 先把新数据插入到临时…

【深度学习】单层神经网络

单层神经网络 神经元感知机 1943年&#xff0c;心理学家McCulloch和数学家Pitts共同发表了神经网络的开山之作A Logical Calculus of the Ideas Immanent in Nervours Activity1&#xff0c;提出了神经网络的第一个数学模型——MP模型。该模型也成为了人工神经网络的基础。 神经…

AXI DMA IP的MICRO DMA模式和去掉SG(Scatter-Gather)功能的模式

AXI DMA IP的MICRO DMA模式和去掉SG&#xff08;Scatter-Gather&#xff09;功能的模式确实有一些区别。让我们详细比较这两种模式&#xff1a; 功能复杂度&#xff1a; MICRO DMA模式&#xff1a;设计为更简单、更轻量级的DMA解决方案。无SG模式&#xff1a;仍保留了基本DMA的…

Error hdl vendor backen is missing

跑vcs时报这个错&#xff0c; // hdl vendor backends are defined for VCS,QUESTA,INCA #if defined(VCS) || defined(VCSMX) #include "uvm_hdl_vcs.c" #else #ifdef QUESTA #include "uvm_hdl_questa.c" #else #if defined(INCA) || defined(NCSC) #in…

leetcode-448. 找到所有数组中消失的数字

题目描述 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&#xff1a;nums [4,3,2,7,8,2,3,1] 输出&#xff1a;[5,6…

代码随想录算法训练营第十四天| 226.翻转二叉树 101. 对称二叉树 104.二叉树的最大深度 111.二叉树的最小深度

目录 一、LeetCode 226.翻转二叉树思路&#xff1a;C代码 二、LeetCode 101. 对称二叉树思路C代码 二、LeetCode 104.二叉树的最大深度思路C代码 二、LeetCode 111.二叉树的最小深度思路C代码 总结 一、LeetCode 226.翻转二叉树 题目链接&#xff1a;LeetCode 226.翻转二叉树 …

Redis缓存配置

redis缓存 使用redis缓存的原因是因为在可能的高并发环境下&#xff0c;mysql数据库无法承受大量的请求&#xff0c;可能会导致数据库崩溃。而这些请求很大一部分都是查询请求&#xff0c;因此采用redis这样的以内存作为存储数据空间的数据库来存储查询请求的数据&#xff0c;…

springboot静态资源访问问题归纳

以下内容基于springboot 2.3.4.RELEASE 1、默认配置的springboot项目&#xff0c;有四个静态资源文件夹&#xff0c;它们是有优先级的&#xff0c;如下&#xff1a; "classpath:/META-INF/resources/", &#xff08;优先级最高&#xff09; "classpath:/reso…