except baseexception会静默捕获keyboardinterrupt和systemexit,导致无法响应ctrl+c和sys.exit();应仅捕获exception或其子类,自定义异常须继承exception,裸except等同于except baseexception,极其危险。

except BaseException: 会吞掉 Ctrl+C 和 sys.exit()
直接写 except BaseException: 或等价的裸 except:,会让脚本失去响应中断和退出的能力。用户按 Ctrl+C 时,KeyboardInterrupt 异常被静默捕获,程序卡在原地;调用 sys.exit() 时,SystemExit 同样被拦下,进程无法终止。
-
KeyboardInterrupt和SystemExit都是BaseException的直系子类,和Exception并列,不归Exception管 - 它们不是“错误”,而是解释器级控制信号:一个代表用户干预,一个代表主动退出流程
- 一旦被
except BaseException:拦住,又没做显式处理(比如重新抛出),就等于废掉了这两个关键机制
Exception 才是业务异常的合理父类
所有你日常遇到的错误——ValueError、TypeError、KeyError、OSError——都继承自 Exception,而不是 BaseException。自定义异常也必须继承 Exception,否则它会被 except Exception: 漏掉,又意外落入 except BaseException: 的陷阱里。
调用 Cutout.Pro 视觉处理 API 进行背景移除、人像抠图和照片增强,支持文件上传与图片 URL 输入。
- 标准库中只有
SystemExit、KeyboardInterrupt、GeneratorExit这三个例外直接继承BaseException - 继承
Exception的自定义类,能被except Exception:正常捕获,且不影响中断和退出 - 写
class MyError(Exception): pass是唯一安全、符合惯例的做法
什么时候真需要捕获 BaseException?几乎不需要
真正需要碰 BaseException 的场景极少,基本只出现在解释器实现、测试框架封装或 REPL 内部逻辑中。普通业务代码里,连 except Exception: 都应尽量避免,优先捕获具体异常类型。
- 若想拦截退出行为(如测试中防止
sys.exit()终止进程),应显式写except SystemExit:,而不是靠BaseException一锅端 -
except BaseException:唯一可接受的用法,是顶层兜底日志记录 + 重新抛出,例如:except BaseException as e: log(e); raise - 但即便如此,也要确认你真的愿意让
KeyboardInterrupt也走这一条路径——多数时候并不愿意
检查你的 except 是否隐式覆盖了系统信号
最容易被忽略的是裸 except:。它看起来省事,实则是 except BaseException: 的语法糖,危险系数最高。哪怕只是临时加个 print 调试,也别用它。
- 用
python -c "import ast; print(ast.parse('try: 1/0\nexcept: pass').body[0].handlers[0].type)"可验证裸except对应的 AST 类型就是BaseException - IDE 或 linter(如 pylint)通常会警告
bare-except,别忽略这类提示 - 如果必须兜底,写明
except Exception:,至少保留Ctrl+C和sys.exit()的有效性
except 时,下意识想一句:“这个 except 会不会让别人按 Ctrl+C 按不出来?”Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










