Python 之-异常处理
异常和错误
part1:程序中难免出现错误,而错误分成两种
1语法错误(这种错误,根本过不了Python解释器的语法检测,必须在程序执行前就改正)
#语法错误示范一、
if
#语法错误示范二、
def test:
pass
#语法错误示范三、
print(haha
2逻辑错误(逻辑错误)
#用户输入不完整(比如输入为空)或者输入非法(输出不是数字)
num = input(“>>:”)
int(num)
#无法完成计算
res1 = 1/0
res2 = 1+'str'
part2:什么是异常
异常就是程序运行时发生错误的信号,在Python中,错误出发的异常如下
part3:Python中的异常种类
在Python中不同的异常可以用不同的类型(Python中统一了类型,类型即类)去标识,不同的异常,一个异常标识一种错误
1触发IndexError
1=["egon",'aa']
1[3]
2触发KeyError
dic={’name‘:’egon‘}
dic['age']
3触发ValueError
s='hello'
int(s)
异常处理
什么是异常?
异常发生之后
异常之后的代码就不执行了
什么是异常处理
Python解释器检测到错误,,触发异常(异常触发后且没被处理的情况下程序就在当前异常处终止,后面的代码不会运行,谁会去用一个运行着突然就崩溃的软件。)
所以你必须提供一种异常处理机制来增强你程序的健壮性与容错性。
如何进行异常处理?
首先须知,异常是由程序的错误引起的,语法上的错误跟异常处无关,必须在程序运行前就修改
一、使用if判断试
正常的代码
num1 input('>>:') #输入一个字符串试试
int(num1)
__author__ = 'Linhaifeng'
num1 = input('>>:')
if num1.isdigit():
int(num1) #我们的正统程序放到了这里,其余的都属于异常处理范畴
elif num1.isspace():
print('输入的是空格,就执行我这里的逻辑')
elif num1 == 0:
print('输入的是空,就执行我这里的逻辑')
else:
print('其他情况,执行我这里的逻辑')
问题一、
使用if的方法我们只为第一段代码加上了异常处理,但这些if,跟你的代码逻辑并无关系,这样你的代码会因为可读性差而不容易被看懂
问题二、
这只是我们代码中的一个小逻辑,如果类似的逻辑多,那么每一次都需要判断这些内容,就会导致我们代码特别冗长。
总结:
1、if判断试的异常处理只能针对某一段代码,对于不同的代码段的相同类型的错误你需要写重复的if来进行处理。
2、在你的程序中频繁的写与程序本身无关,与异常处理有关系的if,会使得你的代码可读性极其的差
3、if是可以解决异常的,只是存在1,2的问题,所以,千万不要妄下定论if不能用来异常处理
你之前用的异常处理机制
def test():
print('test running')
choice_dic={
'1':test
}
while True:
choice = input('>>:').strip()
if not choice or choice not in choice_dic:continue #这便是一种异常处理机制
choice_dic[choice]()
输出:
>>:1
est running
二、Python为每一种定制了一个类型,然后提供了一种特定的语法结构来进行异常处理
part1:基本语法
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
读文件例1:
f = open('a.txt')
g = (line.strip() for line in f )
for line in g:
print(line)
else:
f.close
读文件例2:
try:
f = open('a.txt')
g = (line.strip() for line in f)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
except StopIteration:
f.close()
'''
next(g)会触发迭代f,依次next(g)就可以读取文件的一行行内容,无论文件a.txt有多大,同一时刻内存中只有一行内容。
提示:g是基于文件句柄f而存在的,因而只能在next(g)抛出异常StopIteration后才可以执行f.close()
'''
part2:异常类智能用来处理制定的异常情况,如果非制定异常则无法处理。
# 未捕获到异常,程序直接报错
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print e
part3:多分支
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
part4:万能异常在Python的异常中,有一个万能异常:
Exception,他可以捕获任意异常,即:
s1 = 'hello'
try:
int(s1)
except Exception as e :
print(e)
你可能会说既然有万能异常,那么我直接用上面的种种形式就好了,其他异常可以忽略你说的没错,但是应该分两种情况看
1、如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆去做吧,只有一个Exception就足够了。
Excption
s1 = 'hello'
try:
int(s1)
except Exception as e:
'丢弃或者执行其他逻辑'
print(e)
#如果你统一同Exception没错,是可以捕捉到所有的异常,但意味着你在处理所有异常时都使用同一个逻辑去处理(这里说的逻辑即当前expect下面跟的代码块)
2、如果你想要的效果是,对于不同的异常我们需要定制不同处理逻辑,那就需要用到多分支了。
多分支
s1 = 'hello'
try:
int(s1)
except IndexError as e :
print(e)
except KeyError as e :
print(e)
except ValueError as e :
print(e)
多分支+Exception
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
except Exception as e:
print(e)
part5:异常的其他机构
s1 = 'hello'
try:
int(s1)
except IndexError as e :
print(e)
except KeyError as e :
print(e)
except ValueError as e :
print(e)
#except Exception as e :
# print(e)
else:
print('try 内代码块没有异常则执行我')
finally:
print('乌罗异常与否,都会执行该模块,通常是进行清理工作')
part6:主动触发异常
try:
raise TypeError('类型错误')
except Exception as e:
print(e)
part7:自定义异常
class EvaException(BaseException):
def __init__(self,msg):
self.msg = msg
def __str__(self):
return self.msg
try:
raise EvaException('类型错误')
except EvaException as e:
print(e)
part8:断言
#assert 条件
assert 1==1
assert 1==2
part9:try..except的方法比较if的方法的好处
try..except这种异常处理机制就是取代if那种方式,让你的程序在不牺牲可读性的前提下增强健壮性和容错性
异常处理中为每一个异常定制了异常类型(Python中统一了类与类型,类型即类),对于同一种异常,一个except就可以捕捉到,可以同时处理多段代码的异常,(无需写多个if判断试)减少了代码,增强了可读性
使用try..except的方式
1:把错误处理和真正的工作分开来。
2:代码更易组织,更清晰,复杂的工作任务更容易实现
3:毫无疑问,更安全了,不至于一些的疏忽而使程序意外崩溃了;
什么时候用异常处理
有的同学会这么想,学完了异常处理后,好强大,我要为我的每一段程序都加上try...except,干毛线去思考它会不会有逻辑错误啊,这样就很好啊,多省脑细胞===》2B青年欢乐多
try...except应该尽量少用,因为它本身就是你附加给你的程序的一种异常处理的逻辑,与你的主要的工作是没有关系的
这种东西加的多了,会导致你的代码可读性变差,只有在有些异常无法预知的情况下,才应该加上try...except,其他的逻辑错误应该尽量修正