什么是异常?
异常就是程序运行时发生的错误的信号(在程序出现错误时,则会产生一个异常,若程序)没有处理它, 则会跑出该异常,程序的运行也随之终止。
在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')