Python 异常

作者:最西瓜 来源:《Core Python Programming, Second Edition》CH10. Errors and Exceptions

异常最重要的特征就是它的名字,你去查看所有语言中的标准异常,它们的类功能都被设计的非常简单,可以说除了 message 和 traceback 之外,没有别的更多的东西了,而且几乎都是类似。那么为何要设计如此之多的标准异常呢?光《Python 核心编程》这本书里就列举了 50 个标准异常。原因就在于,它的名字就表达了大部分信息,告知了它是在什么情况下才会产生的。

Python 中常用的异常

NameError         当尝试访问一个未定义的变量时抛出
ZeroDivisionError 当除以 0 时抛出
SyntaxError       当发生语法错误时抛出
IndexError        当数组越界时抛出
KeyError          当请求一个不存在的字典关键字时抛出
IOError           输入/输出错误
AttributeError    访问一个不存在的对象属性时抛出

Python 中的标准异常,SystemExit 和 KeyboardInterrupt 是从 BaseException 继承的控制异常,除此之外 Exception 是 BaseException 的子类,并且所有其它的标准异常都是从 Exception 继承,建议你的异常也从 Exception 继承。

捕获异常

Python捕获异常用 try-except 方式来捕获异常,可以处理以个或者多个异常,在没有发生异常的情况下可以用 else 指定语句执行,可以 finally 块中指定不管是否发生异常都必须执行的语句。语法格式如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
try:
    try_suite
except (Exception1[, Exception2, Exception3, ..., ExceptionN])[as reason]:
    suite_for_exceptions_Exc1_to_ExcN
except ExceptionN1[as reason]:
    suite_for_exception_ExcN1
else:
    suite_for_else
finally:
    suite_for_finally

在 reason 中包含了异常参数,获取异常信息的方式有:str(reason) 或者用 traceback 模块中的 print_exc() 来打印异常调用栈到标准误,format_exc() 将异常调用栈转为字符串。

with 语句

with 语句的作用在于简化释放资源(数据库连接、线程资源、文件句柄)的操作,只有实现了上下文管理协议的对象才能使用 with 语句。目前实现了此协议的有 file 等类,它们必须实现 __context__() __enter__() __exit__() 特殊方法,有个 contextlib 模块帮助简化实现此类协议的实现。

触发异常

触发异常用 raise 语句,基本语法如下: raise SomeException[, args[, traceback]] 其中 args 是传递给 SomeException 的构造函数参数,可以是单个对象也可以是元组。 traceback 用的很少。推荐的做法如下:raise exclass() 或者 raise exclass(args)

创建异常

用户自定义异常必须是继承自 Exception ,以下是范例:

1
2
3
4
5
class ExampleError(Exception):
    def __init__(self, msg):
        self.message = msg
    def __str__(self):
        return self.message