鱼C论坛

 找回密码
 立即注册
查看: 1092|回复: 2

[技术交流] 创建自定义异常

[复制链接]
发表于 2020-4-1 15:32:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
创建自定义异常


问题

在你构建的应用程序中,你想将底层异常包装成自定义的异常。

解决方案

创建新的异常很简单——定义新的类,让它继承自 Exception (或者是任何一个已存在的异常类型)。 例如,如果你编写网络相关的程序,你可能会定义一些类似如下的异常:

  1. class NetworkError(Exception):
  2.     pass

  3. class HostnameError(NetworkError):
  4.     pass

  5. class TimeoutError(NetworkError):
  6.     pass

  7. class ProtocolError(NetworkError):
  8.     pass
复制代码


然后用户就可以像通常那样使用这些异常了,例如:

  1. try:
  2.     msg = s.recv()
  3. except TimeoutError as e:
  4.     ...
  5. except ProtocolError as e:
  6.     ...
复制代码


讨论

自定义异常类应该总是继承自内置的 Exception 类,

或者是继承自那些本身就是从 Exception 继承而来的类。 尽管所有类同时也继承自 BaseException ,

但你不应该使用这个基类来定义新的异常。 BaseException 是为系统退出异常而保留的,

比如 KeyboardInterrupt 或 SystemExit 以及其他那些会给应用发送信号而退出的异常。

因此,捕获这些异常本身没什么意义。 这样的话,

假如你继承 BaseException 可能会导致你的自定义异常不会被捕获而直接发送信号退出程序运行。

在程序中引入自定义异常可以使得你的代码更具可读性,

能清晰显示谁应该阅读这个代码。 还有一种设计是将自定义异常通过继承组合起来。

在复杂应用程序中, 使用基类来分组各种异常类也是很有用的。它可以让用户捕获一个范围很窄的特定异常,比如下面这样的:

  1. try:
  2.     s.send(msg)
  3. except ProtocolError:
  4.     ...
复制代码


你还能捕获更大范围的异常,就像下面这样:

  1. try:
  2.     s.send(msg)
  3. except NetworkError:
  4.     ...
复制代码


如果你想定义的新异常重写了 __init__() 方法, 确保你使用所有参数调用 Exception.__init__() ,例如:

  1. class CustomError(Exception):
  2.     def __init__(self, message, status):
  3.         super().__init__(message, status)
  4.         self.message = message
  5.         self.status = status
复制代码


看上去有点奇怪,不过Exception的默认行为是接受所有传递的参数并将它们以元组形式存储在 .args 属性中。

很多其他函数库和部分Python库默认所有异常都必须有 .args 属性, 因此如果你忽略了这一步,

你会发现有些时候你定义的新异常不会按照期望运行。 为了演示 .args 的使用,

考虑下下面这个使用内置的 RuntimeError` 异常的交互会话, 注意看raise语句中使用的参数个数是怎样的:

  1. >>> try:
  2. ...     raise RuntimeError('It failed')
  3. ... except RuntimeError as e:
  4. ...     print(e.args)
  5. ...
  6. ('It failed',)
  7. >>> try:
  8. ...     raise RuntimeError('It failed', 42, 'spam')
  9. ... except RuntimeError as e:

  10. ...     print(e.args)
  11. ...
  12. ('It failed', 42, 'spam')
  13. >>>
复制代码


关于创建自定义异常的更多信息,请参考 Python 官方文档:https://docs.python.org/3/tutorial/errors.html

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-1 15:35:38 | 显示全部楼层
能不能不要机翻?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-1 16:17:27 | 显示全部楼层

没有机翻
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-28 20:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表