异常
一般情况下,在Python无法正常处理程序时就会发生一个异常。异常是Python对象,在python中,所有异常都必须是继承BaseException类的实例。当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
异常处理
捕捉异常可以使用try…except…else…finally…语句。其中else和finally子句是可以省略的。格式如下,
1
2
3
4
5
6
7
8
|
try:
语句块
except 异常表达式:
except处理语句块
else:
else语句块
finally:
finally语句块
|
按照如下方式工作;
首先,执行try子句(在关键字try和关键字except之间的语句)
如果没有异常发生,忽略except子句,try子句执行完后,依次执行else子句和finally子句后结束。
如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行finally子句。
最后一个except子句,可以没有异常表达式,表示它匹配任何异常。
如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
一个 try语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
else子句必须放在所有的 except 子句后面。else从句只会在没有异常的情况下执行,而且它会在finally语句之前执行。
finally字句是在最后一定会被执行的。
例如:
try…except…语句,捕获不能被零除的异常。
1
2
3
4
5
6
|
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
|
执行以上程序会输出如下结果:
1
2
|
try...
except: division by zero
|
try…except…finally…语句,捕获不能被零除的异常。无论是否有异常,finally子句总是最后被执行。
例如:
1
2
3
4
5
6
7
8
|
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
finally:
print('finally')
|
执行以上程序会输出如下结果:
1
2
3
|
try...
except: division by zero
finally
|
try…except…else…finally…语句语句,捕获不能被零除的异常。有异常时,else子句不会执行。但是finally子句总是最后被执行。
例如:
1
2
3
4
5
6
7
8
9
10
|
try:
print('try...')
r = 10 / 0
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
else:
print('else')
finally:
print('finally')
|
执行以上程序会输出如下结果:
1
2
3
|
try...
except: division by zero
finally
|
try…except…else…finally…语句语句,捕获不能被零除的异常。无异常时,else子句会执行。finally子句总是最后被执行。
例如:
1
2
3
4
5
6
7
8
9
10
|
try:
print('try...')
r = 10 / 1
print('result:', r)
except ZeroDivisionError as e:
print('except:', e)
else:
print('else')
finally:
print('finally')
|
执行以上程序会输出如下结果:
1
2
3
4
|
try...
result: 10.0
else
finally
|
抛出异常
Python使用raise语句抛出一个指定的异常。
例如:
1
2
3
4
|
try:
raise NameError('NoExistValue')
except NameError as e:
print('except:', e)
|
执行以上程序会输出如下结果:
处理多个异常
可以使用三种方法来处理多个异常。
第一种方法需要把所有可能发生的异常放到一个元组。
例如:
1
2
3
4
|
try:
file = open('test.txt', 'rb')
except (IOError, EOFError) as e:
print("An error occurred. {}".format(e.args[-1]))
|
执行以上程序会输出如下结果:
1
|
An error occurred. [Errno 2] No such file or directory: 'test.txt'
|
第二种方式是对每个单独的异常在单独的except语句块中处理。我们想要多少个except语句块都可以。
例如:
1
2
3
4
5
6
|
try:
file = open('test.txt', 'rb')
except EOFError as e:
print("An EOF error occurred.",e)
except IOError as e:
print("An error occurred.",e)
|
执行以上程序会输出如下结果:
1
|
An error occurred. [Errno 2] No such file or directory: 'test.txt'
|
第三种方式是except 子句可以省略异常名,以用作通配符。捕获所有异常。
例如:
1
2
3
4
5
6
|
try:
file = open('test.txt', 'rb')
except EOFError as e:
print("An EOF error occurred.",e)
except:
print("An error occurred.")
|
执行以上程序会输出如下结果:
如果发生的异常和except子句中的类是同一个类或者是except子句中的类的子类,则异常和except子句中的类是兼容的(但反过来则不成立)。
例如,下面的代码将依次打印 Grandpa, Father, Son
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class Grandpa(Exception):
pass
class Father(Grandpa):
pass
class Son(Father):
pass
for instance in [Grandpa, Father, Son]:
try:
raise instance()
except Son:
print("Son")
except Father:
print("Father")
except Grandpa:
print("Grandpa")
|
执行以上程序会输出如下结果:
但是,下面的代码依次打印Grandpa, Grandpa, Grandpa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class Grandpa(Exception):
pass
class Father(Grandpa):
pass
class Son(Father):
pass
for instance in [Grandpa, Father, Son]:
try:
raise instance()
except Grandpa:
print("Grandpa")
except Son:
print("Son")
except Father:
print("Father")
|
执行以上程序会输出如下结果:
1
2
3
|
Grandpa
Grandpa
Grandpa
|
异常参数
发生异常时,它可能具有关联值,显示异常的相关信息,也称为异常参数 。参数的存在和类型取决于异常类型。
except 子句可以在异常名称后面指定一个变量。这个变量和一个异常实例绑定,它的参数存储在 instance.args 中。为了方便起见,异常实例定义了str() ,因此可以直接打印参数而无需引用 .args 。也可以在抛出之前首先实例化异常,并根据需要向其添加任何属性。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
try:
raise Exception('spam', 'eggs')
except Exception as inst:
# 异常实例的类型
print(type(inst))
# 异常参数arguments stored in .args
print(inst.args)
# __str__方法允许直接打印inst
print(inst)
# 异常参数解包
x, y = inst.args
print('x =', x)
print('y =', y)
|
执行以上程序会输出如下结果:
1
2
3
4
5
|
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
|
异常处理程序不仅处理 try 子句中遇到的异常,还处理 try 子句中调用(即使是间接地)的函数内部发生的异常。
例如:
1
2
3
4
5
6
7
8
9
|
#定义引发异常的函数
def this_fails():
x = 1/0
try:
#调用函数,函数内部发生异常
this_fails()
except ZeroDivisionError as err:
print('调用函数时发生的异常:', err)
|
执行以上程序会输出如下结果:
1
|
调用函数时发生的异常: division by zero
|
转载请注明本网址。