Skip to content

🕒 Python 中的定时任务实现

在 Python 中,我们可以使用 APSchedulerschedule 这两个库来实现定时任务。它们分别适用于不同复杂度和需求的项目。

🧰 APScheduler

安装依赖

toml
[tool.poetry.dependencies]
python = "^3.9"
apscheduler = "^3.10.4"

示例代码

python
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime, timedelta

def sch_test(job_type):
    now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    print('时间:{}, {}测试apscheduler'.format(now, job_type))

task = BlockingScheduler(timezone="Asia/Shanghai")
task.add_job(func=sch_test, args=('一次性任务',), trigger='date', next_run_time=datetime.now() + timedelta(seconds=3))
task.add_job(func=sch_test, args=('定时任务',), trigger='cron', second='*/5')
task.add_job(func=sch_test, args=('定时任务',), trigger='interval', hours=1)
task.add_job(func=sch_test, args=('定时任务',), trigger='cron', second='*/5', jitter=30, misfire_grace_time=60)
task.add_job(func=sch_test, args=('循环任务',), trigger='interval', seconds=3)
task.add_job(func=sch_test, args=('每天22:00执行的任务',), trigger='cron', hour=22, minute=0)
task.start()

功能说明

  • date:在特定时间执行一次任务。
  • cron:按 cron 表达式周期执行任务。
  • interval:每隔固定时间间隔执行任务。
  • 支持时区设置(如 Asia/Shanghai)。
  • 支持任务延迟容忍(misfire_grace_time)和随机延迟(jitter)。

🧵 schedule

安装

bash
pip install schedule

示例代码

python
import schedule
import time
import traceback

def make_loop(job, minutes=None, hours=None):
    job()
    
    if minutes or hours:
        if minutes:
            schedule.every(minutes).minutes.do(job)
        elif hours:
            schedule.every(hours).hours.do(job)

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

def test():
    print('test')

def job():
    try:
        test()
    except:
        traceback.print_exc()

make_loop(job, minutes=1)  # 每1分钟执行一次

功能说明

  • 简单易用,适合轻量级定时任务。
  • 支持按分钟、小时等周期执行。
  • 配合 while 循环持续运行任务。

📝 进阶用法:带日志记录的定时任务

python
from apscheduler.schedulers.blocking import BlockingScheduler
from zoneinfo import ZoneInfo
from loguru import logger

logger.add("logs/my_log.log", rotation="1 day", level="INFO")

def main():
    logger.info("开始执行 main 函数")
    try:
        # do task
        logger.info("执行完成")
    except Exception as e:
        logger.error(f"执行过程中发生错误: {e}", exc_info=True)

if __name__ == "__main__":
    main()
    sched = BlockingScheduler(timezone=ZoneInfo("Asia/Shanghai"))
    sched.add_job(main, 'cron', hour=5, minute=0)

    logger.info("启动定时任务调度器")
    try:
        sched.start()
    except (KeyboardInterrupt, SystemExit):
        logger.info("调度器已停止")

说明

  • 使用 loguru 记录日志,便于调试和监控。
  • 使用 zoneinfo 设置时区。
  • 定时在每天早上 5:00 执行任务。

📌 总结:

  • 如果你需要功能强大、支持多种触发器和持久化的任务调度,推荐使用 APScheduler
  • 如果你只需要简单的定时执行逻辑,schedule 是一个轻量而实用的选择。

Released under the MIT License.