如何让Python程序在终端关闭或关机时执行自动保存函数?
Python程序关闭时自动保存:覆盖终端关闭、关机场景的解决方案
问题背景
尝试通过signal或win32api实现Python程序关闭时自动保存,但现有方案仅在Ctrl+C终止程序时生效。直接关闭终端窗口、关机前未手动关闭程序时,自动保存逻辑无法触发。测试代码如下:
import signal from time import sleep def handle_exit(signum, frame): # do something with open('text.txt','w',encoding='utf-8') as f: f.write(f"signal receive:{signum}") signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) while 1: sleep(1)
测试发现直接关闭终端窗口时,文件不会被写入。
分平台解决方案
Windows平台
Windows下关闭终端窗口、注销或关机时,系统会发送控制台事件而非普通信号,需通过ctypes监听相关事件:
import ctypes from time import sleep # 定义回调函数类型 HANDLER_ROUTINE = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_uint) def console_handler(event): # 捕获控制台关闭、注销、关机事件 if event in (0, 2): # CTRL_CLOSE_EVENT、CTRL_LOGOFF_EVENT with open('text.txt', 'w', encoding='utf-8') as f: f.write("Console closed/logoff/shutdown: data saved") return True return False # 注册控制台事件处理器 handler = HANDLER_ROUTINE(console_handler) ctypes.windll.kernel32.SetConsoleCtrlHandler(handler, True) while True: sleep(1)
Linux/macOS平台
类Unix系统中,关闭终端窗口时会向进程发送SIGHUP信号,只需在原有信号处理基础上添加对该信号的监听:
import signal from time import sleep def handle_exit(signum, frame): signal_map = { signal.SIGINT: "SIGINT", signal.SIGTERM: "SIGTERM", signal.SIGHUP: "SIGHUP" } with open('text.txt','w',encoding='utf-8') as f: f.write(f"Signal received: {signal_map.get(signum, str(signum))} - data saved") signal.signal(signal.SIGINT, handle_exit) # 处理Ctrl+C signal.signal(signal.SIGTERM, handle_exit) # 处理正常终止命令 signal.signal(signal.SIGHUP, handle_exit) # 处理终端关闭 while 1: sleep(1)
额外说明
- 若为GUI程序(如Tkinter、PyQt),建议直接监听窗口关闭事件:
- Tkinter:使用
root.protocol("WM_DELETE_WINDOW", save_and_exit)绑定保存逻辑 - PyQt:重写
closeEvent方法实现保存操作
- Tkinter:使用
- 关机场景下,系统留给进程的处理时间有限,确保保存逻辑简洁高效,避免耗时操作导致系统强制终止进程。
内容的提问来源于stack exchange,提问作者キラル
相关产品推荐
相关产品推荐

