Python exec运行子脚本时sys.exit终止主进程的解决办法
问题原因说明
- 你遇到的现象确实是
sys.exit导致主脚本终止,但本质原因是你调用子脚本的方式错误:exec(open('IS_MET_EEv40_RAW.py').read())会将子脚本的所有代码直接注入到当前主进程的运行上下文执行,相当于把子脚本代码原封不动粘贴到主脚本的对应位置运行,不存在独立的子进程。sys.exit()的作用是终止当前正在运行的Python解释器进程,自然会把主脚本一起终止,你外层套的os.system()属于无效代码,exec执行完返回None,os.system(None)不会产生任何作用。
解决方案
方案1:改用子进程调用子脚本(无需修改子脚本代码,最推荐)
使用subprocess模块启动独立的Python进程运行子脚本,子脚本的sys.exit()只会终止自身进程,完全不会影响主脚本运行,替换原来执行子脚本的代码即可:
import subprocess import sys # sys.executable 会自动取当前运行主脚本的Python解释器路径,避免环境版本冲突 # capture_output设为False会将子脚本的输出直接打印到控制台,和原来的表现一致 run_result = subprocess.run( [sys.executable, "IS_MET_EEv40_RAW.py"], capture_output=False, text=True, check=False ) # 可以通过run_result.returncode获取子脚本的退出状态,判断运行结果 print(f"子脚本运行结束,退出码:{run_result.returncode}")
方案2:修改子脚本退出逻辑,替换sys.exit()
如果需要在主进程内直接复用子脚本的逻辑,可以将sys.exit()替换为抛出自定义异常或者封装为带返回值的函数:
方式A:抛自定义异常,主脚本捕获
首先修改子脚本代码:
# 子脚本内先定义自定义异常 class RawDataUpToDateError(Exception): pass # 把原来的sys.exit换成抛异常 if delta.days <= 1: raise RawDataUpToDateError("Raw data is up to date. No new dates available in raw data")
主脚本执行时捕获该异常即可:
try: exec(open("IS_MET_EEv40_RAW.py").read()) except RawDataUpToDateError as e: print(e)
方式B:子脚本逻辑封装为函数(最规范)
把子脚本的所有运行逻辑封装为带返回值的函数,主脚本直接导入调用:
# IS_MET_EEv40_RAW.py 改造后示例 def run_raw_process(): # 原来的所有子脚本逻辑放在这里 if delta.days <= 1: print("Raw data is up to date. No new dates available in raw data") # 返回状态码给主脚本判断 return 1 # 其他正常运行逻辑 return 0
主脚本直接导入调用:
from IS_MET_EEv40_RAW import run_raw_process status_code = run_raw_process() print(f"子逻辑运行结束,状态码:{status_code}")
额外说明
你原来的os.system(exec(open('IS_MET_EEv40_RAW.py').read()))是完全无效的冗余写法,exec会直接在当前进程执行子脚本代码,返回None,os.system接收None不会执行任何操作,建议直接删除。
内容的提问来源于stack exchange,提问作者Amelia
相关产品推荐
相关产品推荐

