异常处理
Python中使用try...except...finally...
来处理异常。简单的栗子:
1 | try: |
如果某段代码出现错误,可以使用try
来包含这段代码,如果执行出错,则后续代码则不会被执行,而是直接跳转到错误处理代码,即except
语句块。如果有finally
语句块,则执行finally
语句块。
在异常处理的流程当中,try
语句中如果没有错误,则except
一定不会被执行,如果有finally
语句块(也可以没有),一定会会执行finally
语句块。
可以有多个except
语句,来处理不同类型的错误,如下面int()函数可能会抛出ValueError
错误,所以使用except
捕获ValueError
。如果没有错误发生,可以再except
语句块后面添加一个else
,当没有错误发生时,自动执行else
语句:
1 | try: |
Python的错误类型都继承自BaseException
,它不仅仅能捕获该类型错误,还能将其子类也捕获。比如:
1 | try: |
第二个except
永远也不会执行,因为UnicodeError
是ValueError
的子类。该错误只能被第一个except
捕获。官方文档描述了有关错误类型的继承关系。
try...except...
可以跨多层调用,比如下面:
1 | def foo(s): |
不需要再每个地方都捕获错误,只要在合适的层次去捕获错误就可以了。
如果没有捕获错误,它就会一直上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。
Python内置的logging模块可以非常容易的记录错误信息,同时,让程序继续执行下去。程序打印完错误信息后会继续执行,并正常退出。
1 | import logging |
log:
1 | $ python3 err_logging.py |
抛出错误:Python内置函数会抛出很多错误,也可以自己编写函数抛出错误。可以定义一个错误的class,选择继承关系,使用raise
语句抛出一个错误的实例:
1 | class FooError(ValueError): |
另外一种处理错误的方式:在捕获错误的时候,打印ValueError!
后,又将错误抛出。这是由于这个函数不知道怎么处理这个错误,所以,最恰当的方式是继续上抛,让顶层调用者去处理。raise
语句如果不带参数,就会把当前的错误按照原样抛出。此外还可以将except
中的raise
一个Error,将一种错误转换成另外一种类型:raise ValueError('input error!')
。
1 | def foo(s): |