(12)异常处理

什么是异常

异常是程序发生错误的信号,一旦程序出错就会产生一种类型的异常,如果该异常没有被程序处理,就抛出来

程序的运行也随即终止

为何要处理异常

为了保障的健壮性

如何处理异常

错误分为两大类:

1: 语法错误: 应该在程序运行前就立即改正

2: 逻辑错误:

2.1 如果错误的发生的条件是可以预知的应该使用if判断进行预防

2.2 如果错误的发生的条件是不可预知的就需要用到python的try...except机制来进行补救

 

出现的异常分为三部分

追踪信息:就是告诉你在哪一行发生了错误

异常类型:就是告诉你异常的类型

异常的值:异常的值就是明确告诉你哪一个部分导致了异常

 

异常处理中的方法

try....except...else的语法

try:
<语句>        #运行别的代码
except <名字>:
<语句>        #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生

 try-finally 语句无论是否发生异常都将执行最后的代码

try:
<语句>
finally:
<语句>    #退出try时总会执行


try:
<语句>
except Exception as e:
<语句> finally: <语句> #退出try时总会执行 raise
 

主动抛异常(自定义异常)

try:
    raise Networkerror("Bad hostname")
except Networkerror,e:
    print e.args

 

常见的逻辑错误

IndexError #发生这个错误一定是索引超出了列表的值的范围
l=['a','b']
l[5]

KeyError #发生这个错误就是没有按照字典的key去取值,字典中不存在key
dic={'x':1}
dic['y']

AttributeError #发生这个错误一定是类下没有这个属性
class Foo:
pass
Foo.x

TypeError #发生这个错误一定是类型错误,比如能被for循环的一定是可迭代类型,数字类型是不可被迭代的
for i in 1:
print(i)

ValueError #发生这个错误一定是值出现了问题,比如int只能将数字转换成整数,而不能讲字符串转换成整数
int('asdfsadf')

ZeroDivisionError # 比如1除0,0不能被1除,就会报这样的错误
1/0

异常处理语法1: 

try:
print(x) #没有定义变量的值肯定会报错
print('==>?')
l=[1,2,3]
l[0]
except NameError as e: #异常处理可以用as语法将异常值放入一个变量中
print('+++>',e) #打印这个变量
print('other code....')

 

异常处理语法2: #多分支

try:
# print(x)
print('==>?')
l=[1,2,3]
l[5]
dic={'x':111}
dic['y']
print('end....')
except NameError as e:
print('+++>',e)
except IndexError as e:
print('===>',e)
except KeyError as e:
print('---->',e)

print('other code....')
PS:一个try语法下可以写很多不同的异常类型,这种写法用于每一种预知的异常有单独的处理方案,就需要每一行异常类型下写处理方案

异常处理语法3: #多分支

try:
# print(x)
print('==>?')
l=[1,2,3]
# l[5]
dic={'x':111}
dic['y']
print('end....')
except (NameError,IndexError,KeyError) as e:
print(e)

print('other code....')
PS:多分支的另一种写法,用于所有的异常都是用同一种处理方案

异常处理语法4:万能异常Exception

try:
# print(x)
print('==>?')
l=[1,2,3]
l[5]
dic={'x':111}
dic['y']
print('end....')
except Exception as e:
print(e)

print('other code....')
PS:包含了所有的异常类型

异常处理语法5:

try:
# print(x)
print('==>?')
l=[1,2,3]
l[5]
dic={'x':111}
dic['y']
print('end....')
except NameError as e:
print('NameError', e)
except IndexError as e:
print('IndexError', e)
except Exception as e:
print(e)

print('other code....')
PS:前面写预知的语法错误类型,最后写一个万能异常用与捕捉其他异常类型

异常处理语法6:try和关键字else连用

try:
# print(x)
print('==>?')
l=[1,2,3]
# l[5]
dic={'x':111}
# dic['y']
print('end....')
except NameError as e:
print('NameError', e)
except IndexError as e:
print('IndexError', e)
except Exception as e:
print(e)
else:
print('当被检测的代码块没有任何异常发生时会执行else的代码')
PS:else目前只能放到最后,当被检测的代码块没有任何异常发生时会执行else的代码

异常处理语法6:try和关键字finally连用

try:
print(x)
print('==>?')
l=[1,2,3]
# l[5]
dic={'x':111}
# dic['y']
print('end....')
except NameError as e:
print('NameError', e)
except IndexError as e:
print('IndexError', e)
e
xcept Exception as e:
print(e)
else:
print('当被检测的代码块没有任何异常发生时会执行else的代码')
finally:
print('无论被检测的代码块有没有异常发生都会执行finally的代码')
PS:如果else和finally同时存在,那么finally就要写在最后,finally意思就是无论被检测的代码块有没有异常发生都会执行finally的代码
PS:finally通常是用来做回收资源的操作,也是个非常重要的关键字
PS:try可以只单纯的和finally连用,中间没有except和esle,try不能单纯的和else连用

 

什么是断言

关键字assert,通常用来测试代码的时候用到

需求就是程序分为上下两部分,上面一部分负责生产数据,下面部分负责处理数据

上半部分程序的成果
res=['a','b',]

assert len(res) == 3 #程序的中间加一行断言判断,如果断言成功就不会触发,会走下面的程序,如果断言失败,则会直接抛出异常,通常测试代码时候会在程序中间加断言,可以定位问题

下半部分程序取数据处理
res[2]

 

自定义异常

class MyException(BaseException): #定义一个类,名称有标识性的,大部分的类是需要继承基类BaseException
def __init__(self,msg): #定义一个__init__方法,里面有一个参数msg就是异常的值
self.msg=msg

def __str__(self): #控制打印信息的显示格式
return '<%s>' %self.msg

raise MyException('错误的提示信息') #主动抛出异常,raise就是主动抛异常的关键字
posted @ 2018-12-16 21:09  clyde_S  阅读(170)  评论(0编辑  收藏  举报