Python从入门到精通(二十四)Python定时执行任务的姿势

Posted 码农飞哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python从入门到精通(二十四)Python定时执行任务的姿势相关的知识,希望对你有一定的参考价值。

您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦
本文将介绍Python定时执行任务的几种方式。
干货满满,建议收藏,需要用到时常看看。 小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~。

前言

实际开发中我们经常要定时执行一些任务。比如:在一个支付系统中要定时执行账单清算任务,定时关闭未支付的订单等等。针对这些场景Python应付起来也是游刃有余的。这里主要有三个模块来执行。这三个模块或者类分别如下:

Timer类

在threading模块中有Timer类,这个类可以用于控制指定函数在特定时间内执行一次。如下下面示例中就是在2秒后执行一次say_hello函数:

from threading import Timer
import threading
def say_hello():
    print(threading.current_thread().name + '码农飞哥,你好')

t = Timer(2, say_hello)
t.start()
print(threading.current_thread().name + '主线程执行完')

运行结果是:MainThread主线程执行完 Thread-1码农飞哥,你好。 从运行结果可以看出Timer是另起线程执行方法的,不会阻塞主线程的执行。
Timer类的弊端就是太简单了,只能执行一次任务,如果要重复执行任务的话,必须要通过循环来实现。针对这种情况在threading模块中提供了scheduler类。

scheduler类

sched模块的scheduler类就可以实现在指定间隔内多次执行任务。其语法结构是:scheduler(timefunc=time.monotonic,delayfunc=time.sleep) 可以向该构造方法中传入2个参数(当然也可以不指定),其中timefunc:指定生成时间戳的函数,默认使用time.monotonic来生成时间戳。
delayfunc: 在未到达指定时间前,通过该参数可以指定阻塞任务的函数,默认采用time.sleep()函数来阻塞程序。
这个类有三个方法,分别是:
1.scheduler.enter(delay, priority, action, argument=(), kwargs=_sentinel) 这个方法的作用是在time规定的时间后,执行action参数指定的函数,其中argument和kwargs负责action指定的函数传参,priority参数指定要执行任务的等级,当同一时间点多个任务要执行时,等级越高(priority值越小)的任务会优先执行,该函数会返回一个event,可用来取消该任务。
2.scheduler.cancel(event): 取消event任务。需要注意的是如果event参数执行的任务不存在时,则会报ValueError错误。
3.scheduler.run(blocking=True):运行所有需要调度的任务,如果调用该方法的blocking参数为True。该方法将会阻塞线程,直到所有被调度的任务都执行完成。
举个例子说明下吧:

import threading
from sched import scheduler


def action(arg):
    print(threading.current_thread().name + ' ' + arg)


def thread_action(*add):
    # 创建任务调度对象
    sche = scheduler()
    # 定义优先级
    i = 1

    for arc in add:
        # 指定1秒后执行action函数
        sche.enter(1, i, action, argument=(arc,))
        i = i + 1
    # 执行所有调度的任务
    sche.run()


# 定义为线程方法传入的参数
my_tuple = ("等级1的任务", '等级2的任务', '等级3的任务')
thread = threading.Thread(target=thread_action, args=my_tuple)
thread.start()

运行结果是:

Thread-1 等级1的任务
Thread-1 等级2的任务
Thread-1 等级3的任务

这种虽然可以在指定间隔的时间内重复执行任务,但是还是不够好使,对于一些比较复杂的定时任务,比如指定每天10点半执行某个任务。每周一执行某个任务则束手无策了。这时候就需要请出schedule模块了。

schedule模块

首先通过 pip install schedule 来安装schedule模块。这个模块的使用也很简单。可以用函数式的方式来调用方法。比如:要每分钟执行方法add,那么它的写法是:
schedule.every(1).minutes.do(add): 其各个方法的解释如下:
every(interval: int = 1): 表示时间间隔,默认是1。
minutes: 表示时间单位是分钟,如果是秒的话则是seconds,小时的话就是hours,天的话则是days。如果指定周一的话就是monday
do:表示需要指定的方法。do(self, job_func: Callable, *args, **kwargs) 其中 job_func表示要调用的方法,*args传入关键字参数,传入的是元组,**kwargs 传入的是字典。
语法格式基本大同小异。

import schedule
import time


def job(name):
    print("他的名字是:", name)


name = "码农飞哥"
# 每隔1分钟执行一次任务
schedule.every(1).minutes.do(job, name)
# 每隔一小时执行一次任务
schedule.every().hour.do(job, name)
# 每天10:30执行一次任务
schedule.every().day.at("10:30").do(job, name)
# 每隔5到10天执行一次任务
schedule.every(5).to(10).days.do(job, name)
# 每周一执行一次任务
schedule.every().monday.do(job, name)
# 每周三13:15执行一次任务
schedule.every().wednesday.at("13:15").do(job, name)

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

schedule 执行任务是串行的。如下图,有两个定时任务,都是每隔1秒执行一次,分别执行job1函数和job2函数。

import schedule
import time
def job1():
    print("任务1开始执行")
    time.sleep(1)
    print("任务1执行完成")


def job2():
    print("任务2开始执行")
    time.sleep(1)
    print("任务2执行完成")


# 每隔1分钟执行一次任务
schedule.every(1).seconds.do(job1)
schedule.every(1).seconds.do(job2)

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

其运行结果是:

任务1开始执行
任务1执行完成
任务2开始执行
任务2执行完成
任务1开始执行
任务1执行完成
任务2开始执行
任务2执行完成
......

可以看出任务1和任务2是完美的串行执行的。也就是说只有任务1执行完了才会执行任务2。那么在并发的情况下是怎样的呢?

import schedule
import time
import threading


def job1():
    print("任务1开始执行\\n")
    time.sleep(1)
    print("任务1执行完成\\n")


def job2():
    print("任务2开始执行\\n")
    time.sleep(1)
    print("任务2执行完成\\n")


def thread_job(fun):
    threading.Thread(target=fun).start()


# 每隔1分钟执行一次任务
schedule.every(1).seconds.do(thread_job, job1)
schedule.every(1).seconds.do(thread_job, job2)

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

运行结果是:

任务1开始执行
任务2开始执行
任务1执行完成
任务2执行完成
任务1开始执行
任务2开始执行
任务1执行完成
任务1开始执行

在并发情况下,任务2不需要等任务1执行完才能执行。

总结

本文详细介绍了Python执行定时任务的各种模块和类。

Python知识图谱

为了更好帮助更多的小伙伴对Python从入门到精通,我从CSDN官方那边搞来了一套 《Python全栈知识图谱》,尺寸 870mm x 560mm,展开后有一张办公桌大小,也可以折叠成一本书的尺寸,有兴趣的小伙伴可以了解一下------扫描下图中的二维码即可购买。

我本人也已经用上了,感觉非常好用。图谱桌上放,知识心中留。

我是码农飞哥,再次感谢您读完本文

以上是关于Python从入门到精通(二十四)Python定时执行任务的姿势的主要内容,如果未能解决你的问题,请参考以下文章

MySQL从入门到精通高级篇(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析

MySQL从入门到精通高级篇(二十四)EXPLAIN中select_type,partition,type,key,key_len字段的剖析

Flask框架从入门到精通之蓝图(二十四)

Flask框架从入门到精通之蓝图(二十四)

Flask框架从入门到精通之蓝图(二十四)

Python爬虫从入门到放弃(二十四)之 Scrapy登录知乎