如何停止运行中的Python脚本且不丢失已生成的列表数据?
嘿,这种跑了超长时间的脚本中途要停还想保留数据的情况,我之前踩过坑,给你几个可行的方案,分情况来看:
方案1:提前给脚本加实时保存逻辑(如果还能修改代码并重启的话)
最稳妥的办法是在填充lists的过程中定期增量保存,避免一次性跑太久前功尽弃。比如用pickle(适合复杂Python对象)或者json(适合简单数据类型):
import pickle import time # 初始化你的目标lists target_lists = [] last_save_time = time.time() def save_progress(): """保存当前lists到文件""" with open('list_progress.pkl', 'wb') as f: pickle.dump(target_lists, f) print(f"已保存进度:当前list长度为 {len(target_lists)}") # 你的主业务逻辑 while True: # 这里是你生成并添加元素到list的代码 new_element = your_processing_function() target_lists.append(new_element) # 两种触发保存的方式二选一: # 1. 每添加N个元素保存一次 if len(target_lists) % 500 == 0: save_progress() # 2. 每隔固定时间(比如1小时)保存一次 # if time.time() - last_save_time >= 3600: # save_progress() # last_save_time = time.time()
方案2:给正在运行的脚本发信号触发保存(如果脚本还在跑)
如果脚本已经在跑,但你之前没加保存逻辑,有两种应对方式:
方式A:提前给脚本加信号处理(下次写长耗时脚本必加)
如果是你自己写的脚本,下次可以提前加上信号处理逻辑,这样收到停止信号时会自动保存数据再退出:
import pickle import signal target_lists = [] def handle_stop_signal(signal_num, frame): """收到停止信号时保存数据再退出""" print("\n收到停止请求,正在保存当前数据...") with open('emergency_save.pkl', 'wb') as f: pickle.dump(target_lists, f) print("保存完成,程序即将退出") exit(0) # 注册信号处理函数:捕获Ctrl+C(SIGINT)和系统终止信号(SIGTERM) signal.signal(signal.SIGINT, handle_stop_signal) signal.signal(signal.SIGTERM, handle_stop_signal) # 你的主逻辑 while True: target_lists.append(your_processing_function())
方式B:用调试工具attach进程手动保存
如果现在脚本已经在跑,没法修改代码,试试用调试工具attach到进程,手动执行保存代码:
- 先找到脚本的进程ID:
ps aux | grep python - 用pdb附加到进程:
python -m pdb -p <进程ID> - 在pdb交互界面里执行保存代码:
import pickle with open('emergency_save.pkl', 'wb') as f: pickle.dump(target_lists, f) # 替换成你实际的list变量名 quit() # 退出进程
后续如何复用已保存的lists
不管用哪种方式保存,后续的代码里都可以轻松加载:
# 用pickle加载复杂对象 import pickle with open('list_progress.pkl', 'rb') as f: loaded_lists = pickle.load(f) # 如果是用json保存的基础类型,就用json.load import json with open('list_progress.json', 'r') as f: loaded_lists = json.load(f) # 现在就可以直接用loaded_lists做后续处理了
小提醒:如果你的lists里包含自定义类,优先用pickle;如果是字符串、数字、列表字典这类基础类型,用json更安全,跨语言也能读取。
内容的提问来源于stack exchange,提问作者CuriousGeorge119




