Python schedule定时任务中如何实现指定函数每日仅运行一次
可靠实现方案
核心逻辑是用执行日期标记替代固定时间点触发,完全规避main执行耗时不稳定导致的漏触发、重复触发问题,不需要调整现有schedule的调度规则。
实现思路
- 在外层作用域维护一个变量,记录
errorTable上一次成功执行的日期 - 每次
main函数运行时,先获取当前日期,和记录的上次执行日期做对比 - 如果两个日期不一致,说明当天还没执行过
errorTable,立即运行该函数,执行成功后再把标记更新为当前日期 - 按你现在main约2分钟跑一次的频率,当天第一次跑到这段判断逻辑就会触发
errorTable,既不会因为卡不准固定时间点漏跑,也不会在同一天重复执行 - 标记更新放在函数执行成功之后,要是
errorTable运行中途报错,标记不会变更,下次main循环时会自动重试,不会出现当天执行失败就漏跑的问题
改造后代码示例
import time import schedule from datetime import date # 外层作用域初始化标记,None代表从未执行过 last_error_table_run_date = None def main(): global last_error_table_run_date # 保留你原有main函数的其他业务逻辑 # ... def errorTable(): # 保留你原有的errorTable业务逻辑 # ... pass # 每日一次逻辑判断 current_date = date.today() if last_error_table_run_date != current_date: errorTable() last_error_table_run_date = current_date file_read.close() while True: try: schedule.run_pending() schedule.every(1).seconds.do(main) except Exception as e: # 建议打印错误信息方便排查,不要裸吞所有异常 print(f"运行异常: {e}") time.sleep(1)
适配程序重启的优化
如果服务存在意外重启的可能,内存里的标记变量会被重置,可能导致重启后当天重复执行一次errorTable。要解决这个问题很简单,不需要引入数据库之类的重依赖,把上次执行的日期存在本地一个普通文本文件里就行:
- 每次做日期判断前,先读取本地文本文件里存储的上次执行日期
errorTable执行成功后,把当前日期写入这个文本文件覆盖旧值- 哪怕程序重启,也能读到历史执行记录,不会重复触发
不推荐其他方案的原因
- 单独给
errorTable绑定schedule的每日固定时间调度:和现有1秒调度main的逻辑容易出现资源竞争,而且如果固定时间点刚好程序在执行其他耗时任务,还是会漏触发 - 时间范围判断(比如判断当前时间在0点-1点区间就执行):只要main在这个时间窗口内运行多次,就会重复触发
errorTable,还要额外加锁逻辑,维护成本更高
内容的提问来源于stack exchange,提问作者B. Ozen
相关产品推荐
相关产品推荐

