如何让Python脚本捕获所有异常但排除手动终止(Ctrl+C)?
解决Python脚本中Ctrl+C被异常捕获拦截的问题
嘿,这个问题我太熟悉了!你遇到的情况是因为Ctrl+C触发的KeyboardInterrupt异常被你的“捕获所有异常”逻辑给兜住了——别担心,调整一下异常捕获的写法就能轻松解决。
先搞清楚背后的原因
在Python里,Ctrl+C会触发KeyboardInterrupt异常,它属于BaseException的子类(而非普通的Exception子类)。如果你的脚本用了except:或者except BaseException:这种“捕获所有异常”的写法,就会把KeyboardInterrupt也一并拦截,导致程序无法正常退出。
两种可行的解决方案
方案1:只捕获普通异常,自动排除中断类异常
这是最推荐的做法——不要捕获所有异常,而是明确捕获Exception类型。因为KeyboardInterrupt和SystemExit(比如调用sys.exit()时触发)都不属于Exception的子类,所以会被自动排除,程序能正常响应Ctrl+C:
while True: try: do_thing() # 你的业务逻辑 except Exception as e: print(f"处理业务异常: {e}") continue # 出现异常后继续循环 # 此时按下Ctrl+C,KeyboardInterrupt会直接触发,程序正常退出
方案2:捕获所有异常,但单独放行中断类异常
如果因为某些特殊需求,你必须捕获几乎所有异常,只需要把KeyboardInterrupt单独拎出来处理,要么重新抛出它让程序正常退出,要么手动终止程序:
while True: try: do_thing() except KeyboardInterrupt: print("用户手动终止程序,正在退出...") raise # 重新抛出异常,让Python按默认逻辑退出 except Exception as e: print(f"处理异常: {e}") continue
或者如果你不想让Python输出默认的中断栈信息,可以直接调用exit():
while True: try: do_thing() except KeyboardInterrupt: print("用户手动终止,程序已退出") exit(0) # 手动退出,返回0表示正常终止 except Exception as e: print(f"异常发生: {e}") continue
如果连sys.exit()触发的SystemExit也想放行,可以把两个异常放在同一个except里:
try: do_thing() except (KeyboardInterrupt, SystemExit): print("程序被终止") raise except Exception as e: print(f"处理异常: {e}") continue
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

