基于datetime模块实现Python脚本每日定时执行的问题求助
问题分析与解决方案
原代码的核心问题
- 第一版代码中,
balance = deposit + percentage会在每次循环时重置余额,覆盖之前的累加值,导致无法正确累计收益。 - 第二版代码缺少等待到目标执行时间的逻辑,只是简单判断当前小时是否为2点,若启动时不是该时间则直接跳过,无法实现每日定时执行;同时循环逻辑不完整,会出现一次性执行的问题。
- 持续循环检查的方式会持续占用系统资源,功耗较高。
更优实现方案
方案一:利用系统定时任务(最省功耗)
这种方式不需要脚本持续运行,而是让系统每天定时触发脚本执行一次,通过文件持久化保存余额状态,是最节省资源的方案。
实现代码
import datetime import json import os # 配置参数 PERCENTAGE = 5 DEPOSIT = 0 EXPIRING_DAYS = 7 # 连续执行7天 STATE_FILE = "balance_state.json" def load_state(): # 读取已保存的余额和日期状态 if os.path.exists(STATE_FILE): with open(STATE_FILE, "r") as f: return json.load(f) # 首次执行初始化状态 start_date = datetime.date.today() expiring_date = start_date + datetime.timedelta(days=EXPIRING_DAYS) return { "balance": DEPOSIT + PERCENTAGE, "current_date": start_date.isoformat(), "expiring_date": expiring_date.isoformat() } def save_state(state): # 保存最新状态到文件 with open(STATE_FILE, "w") as f: json.dump(state, f, indent=2) def main(): state = load_state() current_date = datetime.date.fromisoformat(state["current_date"]) expiring_date = datetime.date.fromisoformat(state["expiring_date"]) # 判断是否已到期 if current_date >= expiring_date: print("已达到期日期,停止执行") os.remove(STATE_FILE) # 清理状态文件 return # 执行余额累加 state["balance"] += PERCENTAGE # 更新下一次执行的日期 next_date = current_date + datetime.timedelta(days=1) state["current_date"] = next_date.isoformat() save_state(state) print(f"今日执行完成,当前余额: {state['balance']},下次执行日期: {next_date}") if __name__ == "__main__": main()
系统定时任务配置
- Linux/macOS:执行
crontab -e,添加以下内容(替换脚本路径):
表示每天凌晨2点自动执行脚本。0 2 * * * /usr/bin/python3 /path/to/your/script.py - Windows:打开「任务计划程序」,创建基本任务:
- 触发时间设置为「每天」,时间选凌晨2点;
- 操作选择「启动程序」,程序选Python的exe路径,添加参数为你的脚本路径。
方案二:脚本内部休眠到目标时间(无需系统定时)
如果不想依赖系统定时任务,可以让脚本计算距离下次执行的时间,直接休眠到目标点,期间CPU占用极低,同样节省功耗。
实现代码
import datetime import time PERCENTAGE = 5 DEPOSIT = 0 EXPIRING_DAYS = 7 TARGET_HOUR = 2 # 每日凌晨2点执行 def calculate_next_run_time(): now = datetime.datetime.now() # 计算今日目标执行时间 target_today = now.replace(hour=TARGET_HOUR, minute=0, second=0, microsecond=0) # 如果当前时间已过今日目标点,就推到明天 if now >= target_today: next_run = target_today + datetime.timedelta(days=1) else: next_run = target_today return next_run def main(): balance = DEPOSIT + PERCENTAGE # 首次执行初始余额 start_date = datetime.date.today() expiring_date = start_date + datetime.timedelta(days=EXPIRING_DAYS) while datetime.date.today() < expiring_date: # 计算需要休眠的时长 next_run = calculate_next_run_time() sleep_seconds = (next_run - datetime.datetime.now()).total_seconds() print(f"等待至{next_run.strftime('%Y-%m-%d %H:%M')}执行,将休眠{sleep_seconds/3600:.2f}小时") time.sleep(sleep_seconds) # 执行余额累加 balance += PERCENTAGE current_date = datetime.date.today() print(f"[{current_date.strftime('%Y-%m-%d')}] 执行完成,当前余额: {balance}") print("已达到期日期,程序结束") if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者Buchii
相关产品推荐
相关产品推荐

