请问如何在Python中手动停止py文件时执行一些善后工作?
比如手动停止 py 文件运行时自动保存一些变量什么的. 找来找去也没找到合适的方法.
请问如何在Python中手动停止py文件时执行一些善后工作?
一般都是用信号量去通知进程自己退出
用 try...except...finally 或者 atexit 模块就行。
1. 用 try...finally(推荐)
这是最直接的方式,finally 块里的代码无论是否发生异常都会执行。
import time
import sys
def cleanup():
print("正在执行清理工作:保存数据、关闭连接...")
# 这里写你的清理逻辑,比如关闭文件、数据库连接等
# with open('data.txt', 'w') as f:
# f.write('Final data')
def main():
try:
while True:
print("程序运行中...按 Ctrl+C 停止")
time.sleep(1)
except KeyboardInterrupt:
print("\n检测到手动中断(Ctrl+C)")
except Exception as e:
print(f"\n程序发生错误: {e}")
finally:
cleanup() # 这里一定会执行
print("清理完成,程序退出")
if __name__ == "__main__":
main()
2. 用 atexit 模块
这个模块用来注册程序正常退出时的清理函数,但注意:它无法处理 kill -9 这种强制终止。
import atexit
import time
def cleanup():
print("执行清理工作")
# 注册清理函数
atexit.register(cleanup)
def main():
while True:
print("程序运行中...")
time.sleep(1)
if __name__ == "__main__":
main()
简单总结:日常用 try...finally 最靠谱。
except KeyboardInterrupt
关键词 python 信号处理 SIGINT
数据量不大的话可以变量更改时在其他地方也写一份,比如用 log,redis 之类的
except KeyboardInterrupt:
pass
<br>import atexit<br>def exit_handler():<br> global config<br> with open('reservoir_simulate.config', 'w') as config_file:<br> config_file.write(json.dumps(config, indent = 4))<br> print('Program finished! Current node = ' +<br> str(config["reservoir"]["start_node"]))<br>if __name__ == '__main__':<br> atexit.register(exit_handler)<br>
[Doing something before program exit]( https://stackoverflow.com/questions/3850261/doing-something-before-program-exit)
Sorry 打错了- -<br>import atexit <br>def exit_handler(): <br> ...<br>if __name__ == '__main__': <br>atexit.register(exit_handler) <br>
try…except 和 atexit 都不行,singal 倒是可以终止程序,但是不能注册函数,如果注册函数,则无法终止程序,处理函数也不会执行:
#main.py
…
def hander(a,b):
print(’…test…’)
if name == ‘main’:
import signal
signal.signal(signal.SIGTERM,hander) #如果注册函数则无法终止程序,不注册则可以终止程序
from PyQt5.QtCore import QCoreApplication
app = QCoreApplication(sys.argv)
main = MainEngine()
main.login()
app.exec_()
#a.py
import signal
import os
os.kill(<pid>,signal.SIGTERM)
signal hander 里要主动调用 sys.exit 退出。kill 信号有很多种,Unix 信号机制了解一下。
atexit 为啥不行,我平时都用这个,就是 ctrl+c 或者 kill -INT $pid 杀死进程的时候,exit_handler()函数都会执行的
信号量
捕获 ctrl+c

