前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python任务调度模块 – APScheduler,Flask-APScheduler实现定时任务

Python任务调度模块 – APScheduler,Flask-APScheduler实现定时任务

作者头像
用户1214487
发布于 2018-07-31 09:32:37
发布于 2018-07-31 09:32:37
4.8K00
代码可运行
举报
文章被收录于专栏:PythonPython
运行总次数:0
代码可运行

1.安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install apscheduler

  安装完毕

2. 简单任务

  首先,来个最简单的例子,看看它的威力。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 
 5 
 6 def aps_test():
 7     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '你好'
 8 
 9 
10 scheduler = BlockingScheduler()
11 scheduler.add_job(func=aps_test, trigger='cron', second='*/5')
12 scheduler.start()

  看代码,定义一个函数,然后定义一个scheduler类型,添加一个job,然后执行,就可以了,代码是不是超级简单,而且非常清晰。看看结果吧。

5秒整倍数,就执行这个函数,是不是超级超级简单?对了,apscheduler就是通俗易懂。

再写一个带参数的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 
 5 
 6 def aps_test(x):
 7     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
 8 
 9 scheduler = BlockingScheduler()
10 scheduler.add_job(func=aps_test, args=('你好',), trigger='cron', second='*/5')
11 scheduler.start()

结果跟上面一样的。

好了,上面只是给大家看的小例子,我们先从头到位梳理一遍吧。apscheduler分为4个模块,分别是Triggers,Job stores,Executors,Schedulers.从上面的例子我们就可以看出来了,triggers就是触发器,上面的代码中,用了cron,其实还有其他触发器,看看它的源码解释。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The ``trigger`` argument can either be:
          #. the alias name of the trigger (e.g. ``date``, ``interval`` or ``cron``), in which case any extra keyword
             arguments to this method are passed on to the trigger's constructor
          #. an instance of a trigger class

看见没有,源码中解释说,有date, interval, cron可供选择,其实看字面意思也可以知道,date表示具体的一次性任务,interval表示循环任务,cron表示定时任务,好了,分别写个代码看看效果最明显。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 
 5 
 6 def aps_test(x):
 7     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
 8 
 9 scheduler = BlockingScheduler()
10 scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5')
11 scheduler.add_job(func=aps_test, args=('一次性任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12))
12 scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3)
13 
14 scheduler.start()

看看结果

其实应该不用我解释代码,大家也可以看出结果了,非常清晰。除了一次性任务,trigger是不要写的,直接定义next_run_time就可以了,关于date这部分,官网没有解释,但是去看看源码吧,看这行代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1     def _create_trigger(self, trigger, trigger_args):
 2         if isinstance(trigger, BaseTrigger):
 3             return trigger
 4         elif trigger is None:
 5             trigger = 'date'
 6         elif not isinstance(trigger, six.string_types):
 7             raise TypeError('Expected a trigger instance or string, got %s instead' % trigger.__class__.__name__)
 8 
 9         # Use the scheduler's time zone if nothing else is specified
10         trigger_args.setdefault('timezone', self.timezone)
11 
12         # Instantiate the trigger class
13         return self._create_plugin_instance('trigger', trigger, trigger_args)

第4行,如果trigger为None,直接定义trigger为'date'类型。其实弄到这里,大家应该自己拓展一下,如果实现web的异步任务。假设接到一个移动端任务,任务完成后,发送一个推送到移动端,用date类型的trigger完成可以做的很好。

3.日志

  好了,scheduler的基本应用,我想大家已经会了,但这仅仅只是开始。如果代码有意外咋办?会阻断整个任务吗?如果我要计算密集型的任务咋办?下面有个代码,我们看看会发生什么情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 
 5 
 6 def aps_test(x):
 7     print 1/0
 8     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
 9 
10 scheduler = BlockingScheduler()
11 scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5')
12 
13 scheduler.start()

还是上面代码,但我们中间故意加了个错误,看看会发生什么情况。

说我们没有log文件,好吧,我们添加一个log文件,看看写的什么。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 import logging
 5 
 6 logging.basicConfig(level=logging.INFO,
 7                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 8                     datefmt='%Y-%m-%d %H:%M:%S',
 9                     filename='log1.txt',
10                     filemode='a')
11 
12 
13 def aps_test(x):
14     print 1/0
15     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
16 
17 scheduler = BlockingScheduler()
18 scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5')
19 scheduler._logger = logging
20 scheduler.start()

终于可以看到了,这时候才看到错误,这个是一定要注意的。

其实,到这里,完全可以执行大多数任务了,但我们为了效率,安全性,再往下面看看,还有什么。

4.删除任务

假设我们有个奇葩任务,要求执行一定阶段任务以后,删除某一个循环任务,其他任务照常进行。有如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 import logging
 5 
 6 logging.basicConfig(level=logging.INFO,
 7                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 8                     datefmt='%Y-%m-%d %H:%M:%S',
 9                     filename='log1.txt',
10                     filemode='a')
11 
12 
13 def aps_test(x):
14     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
15 
16 
17 def aps_date(x):
18     scheduler.remove_job('interval_task')
19     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
20     
21 
22 scheduler = BlockingScheduler()
23 scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5', id='cron_task')
24 scheduler.add_job(func=aps_date, args=('一次性任务,删除循环任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12), id='date_task')
25 scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3, id='interval_task')
26 scheduler._logger = logging
27 
28 scheduler.start()

看看结果,

在运行过程中,成功删除某一个任务,其实就是为每个任务定义一个id,然后remove_job这个id,是不是超级简单,直观?那还有什么呢?

5.停止任务,恢复任务

看看官方文档,还有pause_job, resume_job,用法跟remove_job一样,这边就不详细介绍了,就写个代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 import datetime
 4 import logging
 5 
 6 logging.basicConfig(level=logging.INFO,
 7                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 8                     datefmt='%Y-%m-%d %H:%M:%S',
 9                     filename='log1.txt',
10                     filemode='a')
11 
12 
13 def aps_test(x):
14     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
15 
16 
17 def aps_pause(x):
18     scheduler.pause_job('interval_task')
19     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
20 
21 
22 def aps_resume(x):
23     scheduler.resume_job('interval_task')
24     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
25 
26 scheduler = BlockingScheduler()
27 scheduler.add_job(func=aps_test, args=('定时任务',), trigger='cron', second='*/5', id='cron_task')
28 scheduler.add_job(func=aps_pause, args=('一次性任务,停止循环任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=12), id='pause_task')
29 scheduler.add_job(func=aps_resume, args=('一次性任务,恢复循环任务',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=24), id='resume_task')
30 scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3, id='interval_task')
31 scheduler._logger = logging
32 
33 scheduler.start()

看看结果

 是不是很容易?好了,删除任务,停止任务,恢复任务就介绍到这,下面我们看看监听任务。

6.意外

任何代码都可能发生意外,关键是,发生意外了,如何第一时间知道,这才是公司最关心的,apscheduler已经为我们想到了这些。

看下面的代码,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 # coding:utf-8
 2 from apscheduler.schedulers.blocking import BlockingScheduler
 3 from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR
 4 import datetime
 5 import logging
 6 
 7 logging.basicConfig(level=logging.INFO,
 8                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
 9                     datefmt='%Y-%m-%d %H:%M:%S',
10                     filename='log1.txt',
11                     filemode='a')
12 
13 
14 def aps_test(x):
15     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
16 
17 
18 def date_test(x):
19     print datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), x
20     print 1/0
21 
22 
23 def my_listener(event):
24     if event.exception:
25         print '任务出错了!!!!!!'
26     else:
27         print '任务照常运行...'
28 
29 scheduler = BlockingScheduler()
30 scheduler.add_job(func=date_test, args=('一定性任务,会出错',), next_run_time=datetime.datetime.now() + datetime.timedelta(seconds=15), id='date_task')
31 scheduler.add_job(func=aps_test, args=('循环任务',), trigger='interval', seconds=3, id='interval_task')
32 scheduler.add_listener(my_listener, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
33 scheduler._logger = logging
34 
35 scheduler.start()

看看结果

是不是很直观,在生产环境中,你可以把出错信息换成发送一封邮件或者发送一个短信,这样定时任务出错就可以立马就知道了。

  好了,今天就讲到这,以后我们有机会再来拓展这个apscheduler,这个非常强大而且直观的后台任务库。 

7作业运行的控制

add_job的第二个参数是trigger,它管理着作业的调度方式。它可以为date, interval或者cron。对于不同的trigger,对应的参数也相同。

(1). cron定时调度

year (int|str) – 4-digit year month (int|str) – month (1-12) day (int|str) – day of the (1-31) week (int|str) – ISO week (1-53) day_of_week (int|str) – number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun) hour (int|str) – hour (0-23) minute (int|str) – minute (0-59) second (int|str) – second (0-59) start_date (datetime|str) – earliest possible date/time to trigger on (inclusive) end_date (datetime|str) – latest possible date/time to trigger on (inclusive) timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations (defaults to scheduler timezone) 和Linux的Crontab一样,它的值格式为:

Expression

Field

Description

*

any

Fire on every value

*/a

any

Fire every a values, starting from the minimum

a-b

any

Fire on any value within the a-b range (a must be smaller than b)

a-b/c

any

Fire every c values within the a-b range

xth y

day

Fire on the x -th occurrence of weekday y within the month

last x

day

Fire on the last occurrence of weekday x within the month

last

day

Fire on the last day within the month

x,y,z

any

Fire on any matching expression; can combine any number of any of the above expressions

几个例子如下:

1 2 3 4 5

# Schedules job_function to be run on the third Friday # of June, July, August, November and December at 00:00, 01:00, 02:00 and 03:00 sched.add_job(job_function, 'cron', month='6-8,11-12', day='3rd fri', hour='0-3') # Runs from Monday to Friday at 5:30 (am) until 2014-05-30 00:00:00 sched.add_job(job_function, 'cron', day_of_week='mon-fri', hour=5, minute=30, end_date='2014-05-30')

(2). interval 间隔调度

它的参数如下: weeks (int) – number of weeks to wait days (int) – number of days to wait hours (int) – number of hours to wait minutes (int) – number of minutes to wait seconds (int) – number of seconds to wait start_date (datetime|str) – starting point for the interval calculation end_date (datetime|str) – latest possible date/time to trigger on timezone (datetime.tzinfo|str) – time zone to use for the date/time calculations 例子:

1 2

# Schedule job_function to be called every two hours sched.add_job(job_function, 'interval', hours=2)

(3). date 定时调度

最基本的一种调度,作业只会执行一次。它的参数如下: run_date (datetime|str) – the date/time to run the job at timezone (datetime.tzinfo|str) – time zone for run_date if it doesn’t have one already 例子:

1 2 3 4

# The job will be executed on November 6th, 2009 sched.add_job(my_job, 'date', run_date=date(2009, 11, 6), args=['text']) # The job will be executed on November 6th, 2009 at 16:30:05 sched.add_job(my_job, 'date', run_date=datetime(2009, 11, 6, 16, 30, 5), args=['text'])

 7.Flask-APScheduler使用

https://www.jianshu.com/p/2628f566b31c

参考:

https://www.cnblogs.com/yueerwanwan0204/p/5480870.html

http://debugo.com/apscheduler/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
函数连续与某处函数值的关系,从一元到多元
先总结,连续的意思是极限和函数值是一样的,只是极限分左右,所以一般出现是三个等号的成立。
云深无际
2024/11/19
1290
函数连续与某处函数值的关系,从一元到多元
5种函数极限存在的准则
上面的花拳绣腿完成以后,终于可以看一些有用处的东西了,常用的判断函数极限存在的准则:
云深无际
2024/11/21
2410
5种函数极限存在的准则
【机器学习】分而知变,积而见道:微积分中的世界之思
在机器学习的学习旅程中,微积分作为支撑理论之一,是理解模型优化与变化规律的关键。无论是在梯度下降、损失函数优化,还是在复杂模型的训练过程中,微积分都有着举足轻重的作用。在之前的博客中,我们已经介绍了线性代数和概率论的基础,这些都为进一步的学习奠定了基础。今天,我们将深入讲解微积分基础,特别是在机器学习中的应用。
半截诗
2025/01/09
1580
【机器学习】分而知变,积而见道:微积分中的世界之思
武忠祥老师每日一题|第256 - 271题
题目256 设 f(x) = \lim\limits_{n\to\infty}\dfrac{x^{n+2}-x^{-n}}{x^n+x^{-n}} ,则函数 f(x) (A)仅有 1 个间断点 (B)仅有 2 个间断点,其中 1 个可去, 1 个无穷 (C)仅有 2 个间断点, 2 个都是跳跃 (D)有 2 跳跃间断点和 1 个可去间断点 解答 常用极限结论: \lim\limits_{n\to\infty} x^n = \begin{cases} 0 & ,|x| < 1 \\\\ \infty &
一只野生彩色铅笔
2022/09/20
6050
武忠祥老师每日一题|第304 - 319题
证明极限的存在性: 1. 单调有界准则(抽象型函数) 2. 夹逼准则(具体型函数)
一只野生彩色铅笔
2022/09/20
1.4K0
极限语言ε-δ的理解
“无限接近于X”这个表述方式无法被准确定义。你不能用一个未被定义的词来作为定义本身的一部分。就好像我们写程序一样,一定要保证一开始运行的状态你是可控的。
云深无际
2024/08/21
1840
极限语言ε-δ的理解
离散型随机变量为何不是左连续?
用户11315985
2024/10/16
1460
连续,可偏导,可微之间的关系
f(0,0)=0 在原点处偏导数存在,但函数在原点不连续。(因为分母为0不行啊)。
云深无际
2024/11/21
1780
连续,可偏导,可微之间的关系
函数极限性质(补充邻域概念)
去心邻域确保了函数在趋近于某一点时的变化趋势。通过排除这一点本身,能够更准确地描述函数的局部行为,避免特殊点的干扰。只有在去心邻域内,我们才能讨论函数的极限是否存在以及极限值是多少。
云深无际
2024/11/21
1170
函数极限性质(补充邻域概念)
武忠祥老师每日一题|第368 - 380题
设 \(f(x) = \begin{cases} \dfrac{x-\sin x}{x^3} &,x\ne0\\\\ a&,x=0 \end{cases}\) 处处连续,则
一只野生彩色铅笔
2022/09/20
1.1K0
考研(大学)数学 极限与连续(5)
这个,凑一个等价无穷小,然后就洛必达法则的应用。第二个要分左右极限来做,其次用到的就是凑等价无穷小,技巧要自己去练.
用户9628320
2022/11/23
3020
瞎扯数学分析——微积分(大白话版)
公理体系的例子,想说明人类抽象的另外一个方向:语言抽象(结构抽象已经在介绍伽罗华群论时介绍过)。 为了让非数学专业的人能够看下去,采用了大量描述性语言,所以严谨是谈不上的,只能算瞎扯。 现代数学基础有三大分支:分析,代数和几何。这篇帖子以尽量通俗的白话介绍数学分析。数学分析是现代数学的第一座高峰。 最后为了说明在数学中,证明解的存在性比如何计算解本身要重要得多,用了两个理论经济学中著名的存在性定理(阿罗的一般均衡存在性定理和阿罗的公平不可能存在定理)为例子来说明数学家认识世界和理解问题的思维方式,以及存在性的重要性:阿罗的一般均衡存在性,奠定了整个微观经济学的逻辑基础--微观经济学因此成为科学而不是幻想或民科;阿罗的公平不可能存在定理,摧毁了西方经济学界上百年努力发展,并是整个应用经济学三大支柱之一的福利经济学的逻辑基础,使其一切理论成果和政策结论成为泡影。
统计学家
2021/02/05
2K0
C# 入门深度学习:万字长文讲解微积分和梯度下降
由于学习微积分需要一定的基础知识,但是由于本教程不是数学书,所以不能一一详细介绍基础知识,读者需要自行了解学习初等函数、三角函数等基础知识。
痴者工良
2025/03/26
600
C# 入门深度学习:万字长文讲解微积分和梯度下降
泰勒级数_泰勒公式常用
f(x) = \displaystyle{ \sum_{n=0}^{\infty}A_n x^n }
全栈程序员站长
2022/09/20
1.5K0
泰勒级数_泰勒公式常用
函数与微分
f(x)在点x_{0}处可导 \iff f(x)在点x_{0}处左、右导数皆存在且相等。
宋天伦
2020/07/16
8630
武忠祥老师每日一题|第356 - 367题
对于没有 抽象函数 在的极限,我们的手段就很多了,这里既可以 拆项 做,也可以 洛必达
一只野生彩色铅笔
2022/09/20
9180
高等数学整理极限
极限的定义:在自变量的同一变化过程x -> x0 或x -> ∞中,函数f(x)具有极限A的充要条件是f(x) = A + å,其中å是无穷小。
算法之名
2021/03/05
1.1K0
高等数学整理极限
版本11.2——追求极致的极限
█ 本文译自算法R&D,内核开发工程师 Devendra Kapadia 于2017年11月9日的博客文章: Limits without Limits in Version 11.2. 这是一个序
WolframChina
2018/05/31
9940
一个函数在某一点的极限究竟在什么条件下存在呢?极限存在准则
左极限等于右极限: 一个函数在某一点的极限存在,当且仅当该点的左极限和右极限都存在且相等。
云深无际
2024/11/21
3060
一个函数在某一点的极限究竟在什么条件下存在呢?极限存在准则
MATLAB-微积分
MATLAB 中有些问题需要使用微积分来解决,MATLAB提供微分方程求解任何限制的程度和计算方法,并且可以很容易地绘制图形复变函数,并检查最大值,最小值和图形解决原始函数,以及其衍生的其他内容。
用户9925864
2022/07/27
4330
MATLAB-微积分
相关推荐
函数连续与某处函数值的关系,从一元到多元
更多 >
LV.1
华为全栈工程师
目录
  • 1.安装
  • 2. 简单任务
  • 3.日志
  • 4.删除任务
  • 5.停止任务,恢复任务
  • 6.意外
  • 7作业运行的控制
    • (1). cron定时调度
    • (2). interval 间隔调度
    • (3). date 定时调度
  •  7.Flask-APScheduler使用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档