在程序中引入自定义异常可以使得你的代码更具可读性,能清晰显示谁应该阅读这个代码。 还有一种设计是将自定义异常通过继承组合起来。在复杂应用程序中, 使用基类来分组各种异常类也是很有用的。它可以让用户捕获一个范围很窄的特定异常,比如下面这样的:
try:
s.send(msg)
except ProtocolError:
...
你还能捕获更大范围的异常,就像下面这样:
try:
s.send(msg)
except NetworkError:
...
如果你想定义的新异常重写了 __init__() 方法, 确保你使用所有参数调用 Exception.__init__() ,例如:
class CustomError(Exception):
def __init__(self, message, status):
super().__init__(message, status)
self.message = message
self.status = status
看上去有点奇怪,不过Exception的默认行为是接受所有传递的参数并将它们以元组形式存储在 .args 属性中. 很多其他函数库和部分Python库默认所有异常都必须有 .args 属性, 因此如果你忽略了这一步,你会发现有些时候你定义的新异常不会按照期望运行。 为了演示 .args 的使用,考虑下下面这个使用内置的 RuntimeError` 异常的交互会话, 注意看raise语句中使用的参数个数是怎样的:
>>> try:
... raise RuntimeError('It failed')
... except RuntimeError as e:
... print(e.args)
...
('It failed',)
>>> try:
... raise RuntimeError('It failed', 42, 'spam')
... except RuntimeError as e:
... print(e.args)
...
('It failed', 42, 'spam')
>>>
创建新的异常很简单——定义新的类,让它继承自 Exception (或者是任何一个已存在的异常类型)。 例如,如果你编写网络相关的程序,你可能会定义一些类似如下的异常:
class NetworkError(Exception):
pass
class HostnameError(NetworkError):
pass
class TimeoutError(NetworkError):
pass
class ProtocolError(NetworkError):
pass
然后用户就可以像通常那样使用这些异常了,例如:
try:
msg = s.recv()
except TimeoutError as e:
...
except ProtocolError as e:
...
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。