09 异常处理
本章内容
1、异常
2、捕获异常
3、清理操作
------------------------------
对于出错代码,Python提供了一个特殊的异常处理结构,可用于捕获异常,并确保无论出现异常都将执行清理代码;
1、异常
一个异常例子 IOError,当你视图打开不存在的文件的时候将引发这种错误:
最后提示,FileNotFoundError,无法获取文件;
引发异常
Python的内置函数和库函数在引用的时候发生的错误:
语法错误也会导致异常:
在代码的任意地方,我们可以使用raise语句 故意引发错误;
还有很多异常结果可以在官网上查找到;
2、捕获异常
在发生异常的时候,我们可以选择两种方式:
1、忽略异常,让程序崩溃并显示栈跟踪;
2、铺货异常,并打印友好的错误消息乃至视图修复问呗;
捕获异常示例:假设你要从用户那里获取一个整数,为此你反复提示用户,知道用户输入有效的整数:
def get_age(): while True: try: n = int(input('How old are you?')) return n except ValueError: print('Please enter an integer value.')
这个函数中的while循环是一个try/except块。你可将可能引发异常的代码放在try块中;
try块中的代码出现异常,就将跳过其他所有未执行的语句,立即跳转到except块。在上面的语句中,如果try中出现异常,就会跳过return语句;
try/except 块
try/except块的工作原理有点像if语句,但存在一个重大的不同:if语句根据布尔类型表达式的结果决定运行的代码。
int()还会引发多种异常,则代码如下:
这表明int()至少会出于两个不同的原因引发异常ValueError,还至少会出于另一个原因引发异常TypeError。
捕获多种异常
可编写处理多种异常,一种情况如下:
def convert_to_int1(s, base): try: return int(s, base) except (ValueError, TypeError): return 'error'
如果要分别处理不同的异常,可使用多个except子句:
def convert_to_int2(s, base): try: return int(s, base) except ValueError: return 'value error' except TypeError: return 'type error'
捕获所有异常:
如果你在except子句中没有指定异常,它将捕获所有异常:
def convert_to_int3(s, base): try: return int(s, base) except: return 'error'
上面的语句则只关心是否发生了错误,而不会去关心发生了那种错误;
3、清理操作
在try/except结构中,可以添加finally代码块,用来做清理:
def invert(x): try: return 1/x except ZeroDivisionError: return 'error' finally: print('invert(%s) done' % x)
不过是否出错,最后都要执行finally代码块。这个功能特别有用,例如:通常将关闭的文件的语句放在finally块中,这样文件肯定会被关闭,即便发生了IOError异常;
with语句:
清理操作还可以通过with语句来实现,例如:
num = 1 f = open(fname) for line in f: print('%04d %s' % (num, line), end = '') num = num + 1 # 后续代码
这里,我们并不知道对象 f 合适关闭,它是在for循环结束后,可能会结束,但是不知道具体的时间;换句话说,如果这个 f 文件在使用的时候,被别人访问了,就可能出现错误;
为了确保不再需要的文件被尽早的被关闭,我们可以使用with语句来实现,如下:
num = 1 wiith open(fname, 'r') as f: for line in f: print('%04d $s' % (num, line), end = '') num = num + 1
这个代码片段的屏幕输出与前一个代码片段的相同,但使用with语句时,将在for循环结束后立即执行文件对象清理操作(即关闭文件),避免了不再需要的f处于打开状态;