
Python 的 schedule 库本身不自动运行任务,必须显式调用 schedule.run_pending() 并配合循环持续检查,否则定义的任务永远不会触发。
python 的 `schedule` 库本身不自动运行任务,必须显式调用 `schedule.run_pending()` 并配合循环持续检查,否则定义的任务永远不会触发。
schedule 是一个轻量、易用的 Python 定时任务库,但它不是后台服务或守护进程——它只是一个任务注册与调度器,所有任务都需由开发者主动“驱动”执行。你提供的代码:
def test_schedule(test_string):
print(test_string)
schedule.every().day.at("13:00", "Europe/Madrid").do(test_schedule, "test")
仅完成了任务注册(即把函数和触发条件存入内部队列),但未启动调度循环,因此程序执行完就退出,任务自然不会运行。
✅ 正确做法是:在主程序中加入一个持续运行的循环,定期调用 schedule.run_pending(),并辅以合理休眠避免 CPU 空转。标准实践如下:
import schedule
import time
def test_schedule(test_string):
print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {test_string}")
# 注册每日 13:09:30(西班牙马德里时间)执行的任务
schedule.every().day.at("13:09:30", "Europe/Madrid").do(test_schedule, "test")
# 启动调度循环
while True:
schedule.run_pending() # 检查并执行到期任务
time.sleep(1) # 每秒检查一次(精度足够,且资源友好)
⚠️ 注意事项:
- 时区支持依赖 pytz 或 zoneinfo(Python ≥3.9):确保已安装 pytz(pip install pytz),否则带时区的 .at(..., tz) 会报错;
- time.sleep() 时间不宜过长:若设为 60 秒,则任务最多延迟 59 秒执行;推荐 1 秒或 0.5 秒以兼顾精度与性能;
- 避免阻塞主线程:在 Telegram Bot 等异步应用中,不应直接使用 while True 阻塞主事件循环。应改用线程(threading.Thread)或异步适配器(如 schedule + asyncio.to_thread),或选用原生异步方案(如 APScheduler 的 AsyncIOScheduler);
- 日志与错误隔离:生产环境中建议用 logging 替代 print,并在 do() 中包裹异常处理,防止单个任务失败导致整个调度中断。
? 总结:schedule 的核心设计哲学是“显式优于隐式”。它不启动后台线程,也不接管事件循环——这赋予了你完全的控制权,但也意味着你必须负责驱动它。只要加上 run_pending() + 循环 + 合理休眠,你的每日 Telegram 任务就能准时、稳定地运行。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











