为什么在Python中建议从Exception派生而不是BaseExceptionclass?

Why is it recommended to derive from Exception instead of BaseException class in Python?

Python 2 documentation 表示 "programmers are encouraged to derive new exceptions from the Exception class or one of its subclasses, and not from BaseException"。没有进一步解释原因。

很好奇为什么会这样推荐?是否只是为了保留 Python 开发人员设想的 exceptions hierarchy

>>> dir(BaseException) == dir(Exception)
True

BaseException 派生的异常是:GeneratorExitKeyboardInterruptSystemExit

根据文档:

  • GeneratorExit:调用生成器的 close() 方法时引发。它直接继承自 BaseException 而不是 StandardError,因为它在技术上不是错误。
  • KeyboardInterrupt:当用户按下中断键(通常是 Control-C 或 Delete)时引发。在执行期间,定期检查中断。当内置函数 input() 或 raw_input() 等待输入时键入的中断也会引发此异常。 异常继承自BaseException,以免被捕获Exception的代码意外捕获,从而阻止解释器退出。
  • SystemExit:异常继承自BaseException,而不是StandardError或Exception,这样就不会被捕获Exception的代码意外捕获。 这允许异常正确向上传播并导致解释器退出。

所以通常的原因是防止try ... except Exception不小心阻止解释器退出(GeneratorExit除外)

更新 看到 Ashwini Chaudhary 的评论后:

PEP 352 - Required Superclass for Exceptions说明原因。

With the exception hierarchy now even more important since it has a basic root, a change to the existing hierarchy is called for. As it stands now, if one wants to catch all exceptions that signal an error and do not mean the interpreter should be allowed to exit, you must specify all but two exceptions specifically in an except clause or catch the two exceptions separately and then re-raise them and have all other exceptions fall through to a bare except clause:

except (KeyboardInterrupt, SystemExit):
    raise
except:
    ...

That is needlessly explicit. This PEP proposes moving KeyboardInterrupt and SystemExit to inherit directly from BaseException.