首页
关于
友链
Search
1
ESXI 一些功能调整
443 阅读
2
SoftEther 客户端篇
423 阅读
3
天翼云网关3.0/4.0超管密码
414 阅读
4
SoftEther 服务端篇
308 阅读
5
远程桌面rustdesk使用说明
255 阅读
默认分类
代码相关
vue
html
python
系统
数据库
docker
安卓
软件分享
杂七杂八的工具
游戏分享
游戏相关
我的家庭影院
Ai
登录
Search
标签搜索
python
esxi
git
SoftEther
linux
apscheduler
在线
rclone
Ubuntu
list
列表
idm
激活码
Charles
pdf
免安装
鲁大师
图片查看器
蜂蜜浏览器
honeyview
哥特式
累计撰写
98
篇文章
累计收到
16
条评论
首页
栏目
默认分类
代码相关
vue
html
python
系统
数据库
docker
安卓
软件分享
杂七杂八的工具
游戏分享
游戏相关
我的家庭影院
Ai
页面
关于
友链
搜索到
82
篇与
的结果
2022-05-26
APScheduler最基本的用法: “定时几秒后启动job”
APScheduler最基本的用法: “定时几秒后启动job”两种调度器: BackgroundScheduler和BlockingScheduler的区别,job执行时间大于定时调度时间特殊情况的问题及解决方法每个job都会以thread的方式被调度。1、基本的定时调度APScheduler是python的一个定时任务调度框架,能实现类似linux下crontab类型的任务,使用起来比较方便。它提供基于固定时间间隔、日期以及crontab配置类似的任务调度,并可以持久化任务,或将任务以daemon方式运行。下面是一个最基本的使用示例:from apscheduler.schedulers.blocking import BlockingScheduler def job(): print('job 3s') if __name__=='__main__': sched = BlockingScheduler(timezone='MST') sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start()它能实现每隔3s就调度job()运行一次,所以程序每隔3s就输出'job 3s'。通过修改add_job()的参数seconds,就可以改变任务调度的间隔时间。2、BlockingScheduler与BackgroundScheduler区别APScheduler中有很多种不同类型的调度器,BlockingScheduler与BackgroundScheduler是其中最常用的两种调度器。那他们之间有什么区别呢? 简单来说,区别主要在于BlockingScheduler会阻塞主线程的运行,而BackgroundScheduler不会阻塞。所以,我们在不同的情况下,选择不同的调度器:BlockingScheduler: 调用start函数后会阻塞当前线程。当调度器是你应用中唯一要运行的东西时(如上例)使用。BackgroundScheduler: 调用start后主线程不会阻塞。当你不运行任何其他框架时使用,并希望调度器在你应用的后台执行。下面用两个例子来更直观的说明两者的区别。BlockingScheduler例子from apscheduler.schedulers.blocking import BlockingScheduler import time def job(): print('job 3s') if __name__=='__main__': sched = BlockingScheduler(timezone='MST') sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start() while(True): # 不会被执行到 print('main 1s') time.sleep(1) 运行这个程序,我们得到如下的输出:job 3s job 3s job 3s job 3s 可见,BlockingScheduler调用start函数后会阻塞当前线程, 导致主程序中while循环不会被执行到。 BackgroundScheduler例子from apscheduler.schedulers.background import BackgroundScheduler import time def job(): print('job 3s') if __name__=='__main__': sched = BackgroundScheduler(timezone='MST') sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start() while(True): print('main 1s') time.sleep(1) 可见,BackgroundScheduler调用start函数后并不会阻塞当前线程,所以可以继续执行主程序中while循环的逻辑。main 1s main 1s main 1s job 3s main 1s main 1s main 1s job 3s 通过这个输出,我们也可以发现,调用start函数后,job()并不会立即开始执行。而是等待3s后,才会被调度执行。如何让job在start()后就开始运行如何才能让调度器调用start函数后,job()就立即开始执行呢?其实APScheduler并没有提供很好的方法来解决这个问题,但有一种最简单的方式,就是在调度器start之前,就运行一次job(),如下from apscheduler.schedulers.background import BackgroundScheduler import time def job(): print('job 3s') if __name__=='__main__': job() # 执行一次就好了哟 sched = BackgroundScheduler(timezone='MST') sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start() while(True): print('main 1s') time.sleep(1) 这样就能得到如下的输出job 3s main 1s main 1s main 1s job 3s main 1s main 1s main 1s这样虽然没有绝对做到“让job在start()后就开始运行”,但也能做到“不等待调度,而是刚开始就运行job”。如果job执行时间过长会怎么样如果执行job()的时间需要5s,但调度器配置为每隔3s就调用一下job(),会发生什么情况呢?我们写了如下例子:from apscheduler.schedulers.background import BackgroundScheduler import time def job(): print('job 3s') time.sleep(5) if __name__=='__main__': sched = BackgroundScheduler(timezone='MST') sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start() while(True): print('main 1s') time.sleep(1)运行这个程序,我们得到如下的输出:main 1s main 1s main 1s job 3s main 1s main 1s main 1s Execution of job "job (trigger: interval[0:00:03], next run at: 2018-05-07 02:44:29 MST)" skipped: maximum number of running instances reached (1) main 1s main 1s main 1s job 3s main 1s可见,3s时间到达后,并不会“重新启动一个job线程”,而是会跳过该次调度,等到下一个周期(再等待3s),又重新调度job()。为了能让多个job()同时运行,我们也可以配置调度器的参数max_instances,如下例,我们允许2个job()同时运行:from apscheduler.schedulers.background import BackgroundScheduler import time def job(): print('job 3s') time.sleep(5) if __name__=='__main__': job_defaults = { 'max_instances': 2 } sched = BackgroundScheduler(timezone='MST', job_defaults=job_defaults) sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start() while(True): print('main 1s') time.sleep(1)运行程序,我们得到如下的输出:main 1s main 1s main 1s job 3s main 1s main 1s main 1s job 3s main 1s main 1s main 1s job 3s每个job是怎么被调度的通过上面的例子,我们发现,调度器是定时调度job()函数,来实现调度的。那job()函数会被以进程的方式调度运行,还是以线程来运行呢?为了弄清这个问题,我们写了如下程序:from apscheduler.schedulers.background import BackgroundScheduler import time,os,threading def job(): print('job thread_id-{0}, process_id-{1}'.format(threading.get_ident(), os.getpid())) time.sleep(50) if __name__=='__main__': job_defaults = { 'max_instances': 20 } sched = BackgroundScheduler(timezone='MST', job_defaults=job_defaults) sched.add_job(job, 'interval', id='3_second_job', seconds=3) sched.start() while(True): print('main 1s') time.sleep(1)运行程序,我们得到如下的输出:main 1s main 1s main 1s job thread_id-10644, process_id-8872 main 1s main 1s main 1s job thread_id-3024, process_id-8872 main 1s main 1s main 1s job thread_id-6728, process_id-8872 main 1s main 1s main 1s job thread_id-11716, process_id-8872可见,每个job()的进程ID都相同,但线程ID不同。所以,job()最终是以线程的方式被调度执行。来源:https://www.jb51.net/article/218332.htm
2022年05月26日
82 阅读
0 评论
0 点赞
2022-05-24
filter的基础用法
filter的基础用法对于列表(或其他序列类型),如果希望从中筛选出满足某个约束条件的子列表,我们一般的做法是使用一个for循环遍历每个元素然后执行相同约束条件判断,将满足条件的放入新的子列表中。例如,从列表中找出所有偶数子列表,并按对应的先后顺序放入子列表中:a = [1, 2, 3, 4, 5] b = [] for i in a: if i % 2 == 0: b.append(i)那么如果使用filter的话,使用filter函数使得代码变得更简洁:a = [1, 2, 3, 4, 5] def check(i): return i % 2 == 0 b = list(filter(check, a))示例content = "### #123 #234#568 #566#569#565#568" listdata = [i.strip() for i in content.split("#")] c = list(set(filter(lambda o: o, listdata))) print(listdata) print(c) # 输出 ['', '', '', '', '123', '234', '568', '566', '569', '565', '568'] ['566', '569', '565', '234', '123', '568']
2022年05月24日
76 阅读
0 评论
0 点赞
2022-05-24
对列表内的字典进行排序
降序排序alldate = [{'学号': 2.0, '姓名': '李四', '科目': '数学', '成绩': 77.0}, {'学号': 3.0, '姓名': '王五', '科目': '数学', '成绩': 78.0}, {'学号': 1.0, '姓名': '张三', '科目': '数学', '成绩': 90.0}, {'学号': 3.0, '姓名': '王五', '科目': '英语', '成绩': 76.0}, {'学号': 1.0, '姓名': '张三', '科目': '英语', '成绩': 90.0}, {'学号': 2.0, '姓名': '李四', '科目': '英语', '成绩': 91.0}, {'学号': 1.0, '姓名': '张三', '科目': '语文', '成绩': 88.0}, {'学号': 3.0, '姓名': '王五', '科目': '语文', '成绩': 88.0}, {'学号': 2.0, '姓名': '李四', '科目': '语文', '成绩': 89.0}] # 升序排序将reverse去掉即可 alldate.sort(key=lambda x: (x['成绩']), reverse=True) # alldate.reverse() print(alldate)多条件排序alldate.sort(key=lambda x: (x['成绩'], x['科目'])) # 按照科目和成绩进行双排序
2022年05月24日
24 阅读
0 评论
0 点赞
2022-05-09
Python *args和**kwargs
我们知道splat运算符解包多个值,并且知道函数参数有两种类型。若现在还未弄明白,那么可以将*args理解为变元的缩写,而**kwargs理解为关键字变元的缩写。各参数用于解压其各自的变元类型,允许使用可变字长变元列表进行函数调用。例如,创建一个函数表示学生的考试分数。def printScores(student,*scores): print(f"Student Name:{student}") for score in scores: print(score) printScores("Jonathan",100, 95, 88, 92, 99) """ Student Name: Jonathan 100 95 88 92 99 """噢,等等,我并未称呼其为*args?是的,“args”是一个标准化规范,但仍然只是一个名称。事实上,在*args中,唯一的星号是真正的参与者,创建了列表,其内容则是来自函数调用的位置参数(在这些定义变元后)。这些理清楚之后,**kwargs就很容易理解了。名称并不重要,重要的是双星号创建了字典,其内容是关键字参数,来自函数调用(在这些定义变元后)。为了更好地演示,我们创建一个函数,输出参加全国英语等级考试的人员名单。def printPetNames(owner,**pets): print(f"Owner Name:{owner}") for pet,name in pets.items(): print(f"{pet}:{name}") printPetNames("Jonathan", dog="Brock",fish=["Larry", "Curly", "Moe"],turtle="Shelldon") """ Owner Name: Jonathan dog: Brock fish: ['Larry', 'Curly', 'Moe'] turtle: Shelldon """
2022年05月09日
21 阅读
0 评论
0 点赞
2022-04-20
Python定时器
import threading import datetime def run(): print(datetime.datetime.now()) timer = threading.Timer(1, run) timer.start() # 这里才开始运行 if __name__ == '__main__': tq = threading.Timer(1, function=run) # 这里是创建线程 tq.start()
2022年04月20日
28 阅读
0 评论
1 点赞
2022-04-06
button和submit
如果是button请将button的类型改为type="button",因为浏览器会认为button按钮默认类型是submit,会提交数据从而导致整个页面刷新在ie浏览器中按钮的type默认是button,在其他浏览器(如火狐,chrome)则是submit
2022年04月06日
33 阅读
0 评论
0 点赞
2022-04-06
vue跨域问题
在vue-cli版本为2.x的情况下修改webpack.dev.conf.js中的devServer对象加入disableHostCheck: truedevServer: { disableHostCheck: true, }vue-cli版本3.0的情况下修改vue.config.jsmodule.exports = { devServer: { disableHostCheck: true, // 或者试试下面这个 allowedHosts:['.xxxx.com','.xxx.com'], 或者是all } }
2022年04月06日
16 阅读
0 评论
0 点赞
1
...
5
6