目录
一、什么是异常
异常指的是在程序运行过程中发生的异常事件,通常是由外部问题(如硬件错误、输入错误)所导致的。在面向对象的编程语言中异常属于对象。
二、使用异常的好处
1、隔离常规代码和错误处理代码
我们希望程序不要出现问题,然而这是不可能的。必然会有错误让我们去处理,但错误的处理并不是我们代码的核心。异常处理机制可以将这些意外情况剥离出来。
2、延迟处理
检测到一个错误是,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处种植,后面的代码不会运行,谁会用一个运行着突然就崩溃的软件。
所以你必须提供一种异常处理机制来增强你程序的健壮性和容错性。
3、异常的精确定位
编程5分钟,找虫2小时,善用异常机制能够节约不少调试的时间。
三、抛异常的方式
1、抛出异常
raise 语句
Python中的raise 关键字用于引发一个异常,基本上和C#和Java中的throw关键字相同,如下所示
import traceback
def throw_error():
raise Exception("抛出一个异常")#异常被抛出,print函数无法执行
print("飞天猪")
throw_error()
2、传递异常
捕捉到了异常,但是又想重新引发它(传递异常),可以使用不带参数的raise语句即可:
def div(a, b):
try:
print(a / b)
except ZeroDivisionError:
print("Error: b should not be 0 !!")
except Exception as e:
print("Unexpected Error: {}".format(e))
else:
print('Run into else only when everything goes well')
finally:
print('Always run into finally block.')
# tests
div(2, 0)
div(2, 'bad type')
div(1, 2)
# Mutiple exception in one line
try:
print(a / b)
except (ZeroDivisionError, TypeError) as e:
print(e)
# Except block is optional when there is finally
try:
open(database)
finally:
close(database)
# catch all errors and log it
try:
do_work()
except:
# get detail from logging module
logging.exception('Exception caught!')
# get detail from sys.exc_info() method
error_type, error_value, trace_back = sys.exc_info()
print(error_value)
raise
-
except
语句不是必须的,finally
语句也不是必须的,但是二者必须要有一个,否则就没有try
的意义了。 -
except
语句可以有多个,Python会按except
语句的顺序依次匹配你指定的异常,如果异常已经处理就不会再进入后面的except
语句。 -
except
语句可以以元组形式同时指定多个异常,参见实例代码。 -
except
语句后面如果不指定异常类型,则默认捕获所有异常,你可以通过logging或者sys模块获取当前异常。 -
如果要捕获异常后要重复抛出,请使用
raise
,后面不要带任何参数或信息。 -
不建议捕获并抛出同一个异常,请考虑重构你的代码。
-
不建议在不清楚逻辑的情况下捕获所有异常,有可能你隐藏了很严重的问题。
-
尽量使用内置的异常处理语句来替换
try/except
语句,比如with
语句,getattr()
方法。
3、自定义异常类型
Python中也可以自定义自己的特殊类型的异常,只需要要从Exception类继承(直接或间接)即可:
class MyError(Exception):
pass
四、注意事项
1、except指定的异常的类型必须和实际异常的类型一致。
2、如果想把多个异常类型写在一起可以:except (异常类型1,异常类型2):
3、如果不知道出现什么异常可以:except Exception as e:
Exception 代表不管什么异常都按这样异常处理(总异常)
4、异常的传递:如果被调用的函数或类,没做异常处理,就会传递到调用它的代码,如果掉用的代码做了异常处理就按该异常处理。