python之异常处理

1、概念

Python 使用异常对象来表示异常状态,并在遇到错误时引发异常。异常对象未被捕获时,进程将终止并显示一条错误信息

1
2
3
4
5
>>> 1/0
# Traceback (most recent call last):
# File "<pyshell#0>", line 1, in <module>
# 1/0
# ZeroDivisionError: division by zero

但是,使用异常的目的一般并不是为了单纯的显示错误信息,而是为了在发生异常的时候能够允许我们采取不同的方式处理,而不是放任整个过程

2、异常类型

(一)内置异常

异常类型 描述
Exception 几乎所有异常类的基类
SyntaxError 语法错误时引发
TypeError 将内置函数用于类型不正确的对象时引发
ValueError 将内置函数用于类型正确但包含的值不正确的对象时引发
AttributeError 引用属性失败时引发
NameError 找不到名称(变量)时引发
IndexError 使用序列中不存在的索引时引发
KeyError 使用映射中不存在的键值时引发
OSError 操作系统不能执行指定任务时引发

(二)自定义异常

1
2
3
4
5
6
7
8
9
>>> class MyException(Exception):
pass

>>> try:
raise MyException('I am a exception')
except MyException as me:
print(me)

# I am a exception

3、异常处理

(一)try - except

我们可以使用 try - except 语句捕获和处理异常,一个没有指定异常名称的 except 语句可以捕获所有异常(但是一般不建议这样做,因为这样得不到任何有用的信息)。一个简单的例子如下

1
2
3
4
5
6
7
>>> try:
string = 'Hello'
num = int(string)
except:
print('exception')

# exception

(二)处理特定异常

在 except 语句后加上异常类的名称,表示处理特定的异常。其中,使用语句 except Exception 几乎能捕获所有的异常,因为 Exception 几乎是所有异常类的基类

1
2
3
4
5
6
7
>>> try:
li = list()
li.add(123)
except AttributeError as e:
print(e)

# 'list' object has no attribute 'add'

(三)处理多个异常

我们还可以使用多个 except 语句处理多个异常。此时,要特别注意它们之间的排列顺序,因为当前面的 except 语句捕获到异常后,将不再执行后面的 except 语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> try:
li = list()
li[0] = 123
except KeyError as e:
print(e)
print('handling error in KeyError')
except IndexError as e:
print(e)
print('handling error in IndexError')
except Exception as e:
print(e)
print('handling error in Exception')

# list assignment index out of range
# handling error in IndexError

(四)异常处理中的 else 语句

使用 else 语句表示没有捕获到异常的时候进行的操作

1
2
3
4
5
6
7
8
>>> try:
num = 1
except Exception as e:
print(e)
else:
print('Successful')

# Successful

(五)异常处理中的 else 语句

使用 finally 语句表示无论是否捕获到异常都进行的操作

1
2
3
4
5
6
7
>>> try:
f = open('testFile.txt','w')
f.write('forTest')
except Exception as e:
print(e)
finally:
f.close()

4、异常与函数

异常与函数有着天然的关系。如果不处理函数中引发的异常,它将向上传播到调用函数的地方。如果在那里也没有得到处理,它将一直向上传递,直至到达主进程。如果主进程也没有处理该异常,则进程将自动终止并显示错误信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>> def faulty():
raise Exception('Error')

>>> def handle_exception():
try:
faulty()
except:
print('Exception Handled')


>>> def ignore_exception():
faulty()


>>> handle_exception()
# Exception Handled
>>> ignore_exception()
# Traceback (most recent call last):
# File "<pyshell#13>", line 1, in <module>
# ignore_exception()
# File "<pyshell#11>", line 2, in ignore_exception
# faulty()
# File "<pyshell#2>", line 2, in faulty
# raise Exception('Error')
# Exception: Error