Python中sys.excepthook仅生效一次,第二次Ctrl+C无法拦截如何解决
问题原因
你当前写法的核心问题是在自定义excepthook中嵌套调用了main_loop():
- 第一次按下Ctrl+C触发
KeyboardInterrupt时,异常被自定义excepthook捕获,此时你直接在钩子函数内部重新启动了主循环,相当于在原有异常调用栈的上层又叠加了一层新的主逻辑调用。 - Python有明确规定:如果自定义
excepthook本身执行过程中又抛出了新异常,系统会直接放弃调用自定义钩子,回退到默认异常处理逻辑打印错误并退出,这就是第二次按Ctrl+C程序直接退出的原因。
解决方案
不推荐用sys.excepthook实现防Ctrl+C中断的需求,更稳定的方案有两种:
方案1:注册SIGINT信号处理函数(推荐)
直接用signal模块监听Ctrl+C触发的SIGINT信号,每次触发后仅执行警告逻辑,不需要中断原有主循环的执行上下文:
import time import signal def sigint_handler(signum, frame): print("WARNING: CTRL+C WAS PRESSED!") def main_loop(): print("starting!") while True: print("tick") time.sleep(1) # 注册SIGINT信号处理逻辑 signal.signal(signal.SIGINT, sigint_handler) if __name__ == "__main__": main_loop()
该方案下无论按多少次Ctrl+C,都会触发警告后自动回到主循环继续运行,不会出现失效问题。
方案2:在主循环内直接捕获KeyboardInterrupt
如果不想引入信号模块,直接在主循环的执行逻辑外层加try-except捕获中断即可:
import time def main_loop(): print("starting!") while True: try: print("tick") time.sleep(1) except KeyboardInterrupt: print("WARNING: CTRL+C WAS PRESSED!") if __name__ == "__main__": main_loop()
内容的提问来源于stack exchange,提问作者user16712485
相关产品推荐
相关产品推荐

