如何实现Python程序报错时自动重执行?(PyCharm多文件科研场景)
实现报错自动重启科研Python程序的几种方案
当然可以搞定这个需求!针对你这种长时间运行的科研程序,我给你几个实用的方案,都是在PyCharm环境下能轻松落地的:
方案1:写个简单的重试包裹脚本(最直接)
不用改原有A.py的代码,新建一个run_with_retry.py脚本放在同一文件夹里,用它来调用A.py的main()方法并处理重试逻辑:
import traceback import logging from A import main # 配置日志,把错误信息写到文件里,方便后续排查 logging.basicConfig( filename='program_retry_log.log', level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s' ) max_retries = 5 # 设置最大重试次数,避免无限循环 retry_count = 0 while retry_count < max_retries: try: print(f"=== 第 {retry_count+1} 次启动程序 ===") main() print("=== 程序正常运行完成! ===") break # 成功执行就跳出循环 except Exception as e: retry_count += 1 error_msg = f"程序报错,重试次数: {retry_count}/{max_retries}" print(error_msg) traceback.print_exc() # 控制台打印详细错误栈 logging.exception(error_msg) # 把错误日志写到文件 if retry_count < max_retries: print("等待2秒后开始重试...\n") import time time.sleep(2) else: print("=== 已达到最大重试次数,停止重试 ===")
之后你在PyCharm里直接运行这个run_with_retry.py就行,它会帮你自动处理报错重试,还会把错误日志存下来,回来的时候一看就知道发生了啥。
方案2:用命令行循环(不用写额外Python脚本)
如果你不想写新的Python文件,也可以用系统的命令行循环来实现。
针对Linux/macOS(Bash)
在PyCharm里新建一个「Shell Script」运行配置,输入以下命令:
MAX_RETRIES=5 COUNT=0 while [ $COUNT -lt $MAX_RETRIES ]; do echo "=== 第 $((COUNT+1)) 次启动程序 ===" python A.py COUNT=$((COUNT+1)) if [ $COUNT -lt $MAX_RETRIES ]; then echo "程序退出,等待3秒后重试...\n" sleep 3 fi done
针对Windows(CMD/PowerShell)
如果是Windows系统,新建「Batch File」配置,输入:
@echo off set MAX_RETRIES=5 set COUNT=0 :loop if %COUNT% equ %MAX_RETRIES% goto end set /a COUNT+=1 echo === 第 %COUNT% 次启动程序 === python A.py echo 程序退出,等待3秒后重试... timeout /t 3 /nobreak >nul goto loop :end echo === 已达到最大重试次数 ===
运行这个命令行配置,效果和Python脚本一样,报错自动重启。
方案3:用第三方库做精细化重试(进阶)
如果你的程序可能出现不同类型的错误,有些错误值得重试(比如临时的IO异常、资源占用过高导致的中断),有些错误是致命的(比如代码逻辑bug),可以用tenacity这个专门做重试的库来精细化控制。
首先安装库:
pip install tenacity
然后修改你的A.py,给main()方法加上重试装饰器:
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type import logging logging.basicConfig(filename='program_errors.log', level=logging.ERROR) # 配置重试规则:最多重试5次,等待时间从2秒指数增长(2s→4s→8s...最多10s),只重试指定类型的异常 @retry( stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=2, max=10), retry=retry_if_exception_type((IOError, RuntimeError)) ) def main(): # 你的原有科研计算代码 pass if __name__ == "__main__": try: main() except Exception as e: logging.exception("最终重试失败,程序终止") print("程序多次重试后仍失败,请查看日志排查问题")
这种方式的好处是可以精准控制哪些错误要重试,避免在致命bug上浪费时间,同时指数递增的等待时间也能避免短时间内频繁占用资源。
几个重要提醒
- 一定要记录日志:不管用哪种方案,都要把错误信息存到文件里,不然重试几次后你根本不知道之前出了什么问题,排查起来会很麻烦。
- 处理中间状态:如果你的程序运行到一半会生成临时文件、部分计算结果,重试前记得清理这些临时数据,或者实现断点续跑(比如用
pickle把当前计算状态保存下来,下次启动时加载),避免影响下一次运行的结果。 - 不要无限重试:一定要设置最大重试次数,不然如果是代码本身的逻辑错误,程序会一直循环重试,白白浪费计算资源。
内容的提问来源于stack exchange,提问作者J.G.




