第 35 章 异常对象 例外对象
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
到目前为止,我对异常到底是什么还故意含糊其辞。正如前一章所建议的,从 Python 2.6 和 3.0 开始,内置异常和用户定义异常都是通过类实例对象来标识的。这就是异常处理所引发和传播的东西,也是与try 语句中命名的异常相匹配的类的来源。
虽然这意味着你必须使用面向对象编程来定义程序中的新异常,并且引入了一个知识依赖关系,使本书的这部分内容无法全面覆盖异常,但基于类和 OOP 的异常提供了许多好处。其中包括基于类的异常:
可以分门别类。编码为类的异常通过提供类别支持未来的更改--未来添加新的异常一般不需要更改
try语句。具有状态信息和行为。异常类为我们提供了一个存储上下文信息和工具的天然场所,用于
try处理程序--实例可以访问附加的状态信息和可调用方法。支持继承:基于类的异常可参与继承层次结构,以获取和定制通用行为--例如,继承的显示方法可为错误信息提供通用的外观和感觉。
正因为这些优点,基于类的异常能很好地支持程序演进和大型系统。正如我们将发现的那样,所有内置异常都由类标识,并组织成继承树,原因已在前面列出。你也可以对自己定义的用户异常进行同样的处理。
事实上,在 Python 3.X 中,我们将学习的内置异常与您定义的新异常是密不可分的。因为 3.X 要求用户定义的异常继承自内置异常超类,这些超类为打印和状态保留提供了有用的默认值,所以编码用户定义异常的任务还涉及到理解 这些内置异常的作用。
备注
版本偏差说明:Python 2.6、3.0 及更高版本要求异常由类定义。此外,3.X 要求异常类直接或间接地从BaseException 内置异常超类派生。正如我们将看到的,大多数程序都继承自这个类的Exception 子类,以支持普通异常类型的 catchall 处理程序--在处理程序中命名它将捕获大多数程序应该捕获的一切。Python 2.X 也允许独立的经典类充当异常,但它要求新式类从内置异常类派生,这一点与 3.X 相同。
例外情况:回到未来
曾经(嗯,在 Python 2.6 和 3.0 之前),可以用两种不同的方式定义异常。这使得try 语句、raise 语句和整个 Python 变得复杂。如今,只有一种方法。这是一件好事:它消除了语言中为了向后兼容性而积累的大量垃圾。因为旧的方法有助于解释为什么今天的异常是这样的,也因为不可能完全抹去一个在近 20 年的时间里被上百万人使用过的东西的历史,所以让我们先简单回顾一下过去,开始我们对现在的探索。
字符串异常就在外面
在 Python 2.6 和 3.0 之前,可以用类实例和字符串对象定义异常。基于字符串的异常在 2.5 中开始发出弃用警告,并在 2.6 和 3.0 中被删除,因此现在您应该使用基于类的异常,如本书所示。不过,如果你使用的是传统代码,你可能仍然会遇到字符串异常。它们也可能出现在几年前编写的书籍、教程和网络资源中 (以 Python 的年限来说,这简直是永恒!)。
字符串异常的使用非常简单--任何字符串都可以,它们根据对象的身份而不是值进行匹配(即使用is ,而不是== ):
C:\code>C:\Python25\python>>>myexc = "My exception string"# Were we ever this young?...>>>try:...raise myexc...except myexc:... ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access