异常
一般情况下,在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
 | 
 
转载请注明本网址。