什么是异常?
异常就是程序运行时发生的错误的信号(在程序出现错误时,则会产生一个异常,若程序)没有处理它, 则会跑出该异常,程序的运行也随之终止。
在python中,一个异常分为三部分:
1:异常的追踪信息
2:异常的类型
3:异常的值
异常又分为两种:
第一种 语法类异常
这类异常应该在程序执行前就改正
#语法错误示范一
if
#语法错误示范二
def test:
pass
#语法错误示范三
class Foo
pass
#语法错误示范四
print(haha
第二种 逻辑上的异常, 这几种都是逻辑上的异常, 不加以修正的话 在程序执行时就会抛出异常。 如果发生这种异常 看到这个异常后就可以根据它去找到错误的地方然后加以修改 下面是简单的列举一下:
# TypeError int类型不可迭代
for i in 3:
pass
# ValueError 值错误
num = input('>>:')
int(num)
# NameError 名字错误
aaa
# IndexError 索引错误
l=['egon','aaa']
l[3]
# KeyError 字典的值错误
dic={'name':'egon'}
dic['age']
# AttributeError 属性错误
class Foo :
pass
Foo.x
#ZeroDivisionError:无法完成计算
res1=1/0
res1=1+'shr'
# FileNotFoundError 文件路径异常 找不到该文件
f=open('a.txt','r',encoding='utf-8')
异常的种类不仅仅只是上面的, 在python中不同的异常可以用不同的类型去标识,一个异常标识一种错误
AttributeError 视图访问一个对象没有的树形, 比如 foo.x , 但是foo没有属性x。
IOError输入/输出异常,基本上是无法打开文件。
ImportError 无法引入模块或包,基本上是路径问题或名称问题。
IndentionError 语法错误(的子类);代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却视图访问x[5].
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+c 被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python 代码非法,代码不能编译(语法错误)
TypeError 传入对象类型与要求的不符合
UnboudLocalError 试图访问一个还未被设置的局部变量, 基本上是 由于有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值得类型是正确的
异常处理
为了保证程序的健壮性与容错性,即在遇到错误时程序不会崩溃,我们需要对异常进行处理
如果错误发生的条件是可预知的, 我们需要用if进行处理:在错误发生之前进行预防:
AGE=10
while True:
age=input('>>: ').strip()
if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
age=int(age)
if age == AGE:
print('you got it')
break
如果错误发生的条件是不可预知, 则需要用到try...except: 在错误发生后进行处理
基本语法为
try:
被检测的代码块
except 异常类型:
try 中一旦检测到异常,就执行这个位置的逻辑
举例:
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()
异常类只能用来处理指定的异常情况 ,如果非指定异常则无法处理。
#1.单分支
s1 = 'hello'
try:
int(s1)
except IndexError as e:# 未捕获异常, 程序直接报错
print(e)
# 2 多分支
s1 ='hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e: # 可以跟多个except
print(e)
except ValueError as e:
print(e)
# 3 万能异常 Exception
s1='hello'
try:
int(s1)
except Exception as e: #r任何异常都可以接受然后将这个异常命名为e, 下面打印出来
print(e)
#4 多分支异常与万能异常
#4.1 如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆的去做吧,只有一个Exception就足够了。
#4.2 如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。
#5 也可以在多分支后来一个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)
#6异常的其他机构
6.1 except 下面还可以个else,else一定要与except连用
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内代码块没有异常则执行我')
#6.2 try :....finally... 最后总结无论怎样
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('无论异常与否,都会执行该模块,通常是进行清理工作')
7:主动触发异常 raise
raise TypeError 类型错误
class People:
def __init__(self,name):
if not isinstance(name,str):
raise TypeError('%s 必须是str类型’ %name
self.name=name
p=People(123)
#调用结果 TypeError: 123 必须是str类型
8 断言 assert 断定某个条件成立 然后在取执行下面的条件
stus=['egon','alex','wxx','lxx']
assert len(stus) > 0 #断定 stus 的长度成立的情况下就执行下面的 代码
print('part2.........')
print('part2.........')
#打印结果
part2.........
part2.........
9:自定义异常
class RegisterError(BaseException):
def __init__(self,msg,user):
self.msg=msg
self.user=user
def __str__(self):
return '<%s:%s>' %(self.user,self.msg)
raise RegisterError('注册失败','teacher')