一,什么是异常处理
异常处理中,有语法错误和逻辑错误异常是程序运行时发生错误的信号,如,崩溃的结果如下:
Traceback (most recent call last):
File "D:/python3-3/异常/一场类型.py", line 1, in <module>
aa
NameError: name 'aa' is not defined
-
注解:aa: 引发异常的错误Traceback:异常的追踪信息NameError: 异常类name 'aa' is not defined :异常值
1.2 异常处理的类
- 异常种类如下:在python中,不同的异常可以用不同的类型(python中统一了类与类型,类型即类)去标识,不同的类对象标识不同的异常,一个异常标识一种错误AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性xIOError 输入/输出异常;基本上是无法打开文件ImportError 无法引入模块或包;基本上是路径问题或名称错误IndentationError 语法错误(的子类) ;代码没有正确对齐IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]KeyError 试图访问字典里不存在的键KeyboardInterrupt Ctrl+C被按下NameError 使用一个还未被赋予对象的变量SyntaxError Python代码非法,代码不能编译。这是语法错误,写错了TypeError 传入对象类型与要求的不符合UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它ValueError 传入一个调用者不期望的值,即使值的类型是正确的
为了保证程序的健壮性与容错性,即在遇到错误时程序不会崩溃,我们需要对异常进行处理当python解释器检测到错误,触发异常,也可以由程序员自己触发异常,如:raise(编写程序特定的代码,专门用来捕捉这个异常)z一旦捕捉成功则进入另外的处理流程,执行你为其定制的逻辑,从而使程序不会崩溃转载注明来自www.linuxea.com中https://www.linuxea.com/1775.html
-
示例:1,错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防
AGE=10 while True: age=input('>>: ').strip() if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的 age=int(age) if age == AGE: print('输入正确') break
2,多条件
满足预知的多个条件,抛出提示,其他预知之外的else抛出一个异常-
AGE=10 while True: age=input('>>:') if age.isdigit(): age=int(age) if age == AGE: print('你输入10,输入正常') break elif age.isspace(): print('请输入数字,你输入的是空格') elif len(age) == 0: print('请输入数字,你输入的为空') else: print('其他非法输入')
3,例
def BBB(): print('test bbb') choice_dic={ '1':BBB } while True: choice=input('>>:').strip() if not choice or choice not in choice_dic: continue # 这便是异常处理 choice_dic[choice]()
如果输入1则打印test bbb,如果不是则continue,这句也算是异常处理
if not choice or choice not in choice_dic:
continue
在以上的3个例的if判断中,异常处理只能针对某一段代码,对于不同的代码段的相同类型错误需要写重复的if来进行处理这些代码片段其实和程序本身无关,只存在与异常处理有关,尽管if是可以处理异常,但是可读性极差
二,try except
python为每一种一场定制了类型,然后提供了一直特定的语法结构用来进行异常处理如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理当然,我们应该尽量少使用try except,代码本身的逻辑问题应该尽量修正基本语法:
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
异常类只能用来处理指定的异常情况,如果非指定则无法处理
-
示例1
AGE=10 while True: try: age=input('Input Age >>:') age=int(age) if age == AGE: print('你输入10,输入正常') break except ValueError as e: print(e)
将输入非int类型捕捉,ValueError并且被打印
-
示例2:
try: age=input('Input Age >>:') age=int(age) print(age) name=input('Input Name >>:') name=str(name) print(name) except ValueError as e: print(e)
此时如果示例2中的age出错则终止,不会运行name
三,except多分支
可以有多个except如果被捕捉到则执行对应的内容,如果没有捕捉到程序则会崩溃!这样一来,就意味着要写很多except来区分异常。当然,我们需要分场景来看大致是这样的:
try: age=input('Input Age >>:') int(age) name = input('Input Name NUM >>:') int(name) dic={} dic['mark'] a=[] a[100000000] except KeyError as e: print('-K-',e) except ValueError as e: print('-V->',e) except TypeError as e: print('-T-',e) except IndexError as e: print('-I-',e)
四,except Exception多用途异常捕捉
Exception可以捕捉示例中任何异常,在其他中捕捉出现的所有异常假设,我们只想通过一段代码逻辑来处理,无论出现什么异常,统一。那么一个Exception也足够假如,你需要的是对于不同的异常定制不同的处理逻辑,那么就需要多分支了,如本章第三步骤(except多分支),多个except来完成,同时也可以在分支后面加上一个Exception,总之灵活使用
-
一个Exception处理异常:
while True: try: age=input('Input Age >>:') int(age) name = input('Input Name NUM >>:') int(name) dic={} dic['mark'] a=[] a[100000000] except Exception as e: print('请重新输入,输入有误',e) break
-
多个分支与一个Exception:
try: age=input('Input Age >>:') int(age) name = input('Input Name NUM >>:') int(name) dic={} dic['mark'] a=[] a[100000000] except KeyError as e: print('-K-',e) except ValueError as e: print('-V->',e) except TypeError as e: print('-T-',e) except IndexError as e: print('-I-',e) except Exception as e: print('请重新输入,输入有误',e)
五,异常的其他结构
1,有异常则执行异常处理2,当一段代码没有异常做出处理3,无论是否有异常都做出处理在以上三个前提中,如果有异常处理,执行异常处理和finally。如果没有异常则执行else和finally。它并不绝对
-
示例如下:
bbb='linuxea.com' # bbb=123 try: int(bbb) except IndexError as e: print(e) except KeyError as e: print(e) except ValueError as e: print(e) else: print('try内部代码没有异常则执行本条内容') finally: print('无论异常与否,都会执行该模块,通常进行清理工作')
六,主动触发异常raise
除了日常中常见的异常还可以raise主动触发一个异常,仍然可以被捕捉到示例如下:
try: raise TypeError('输入类型错误') except Exception as e: print(e)
七,自定义异常
自定义的异常需要继承一个类BaseException,定义一个类LinuxeaBlog继承BaseExceptionLinuxeaBlog(BaseException)
-
示例如下:
__author__="Linuxea" class LinuxeaBlog(BaseException): def __init__(self,msg): self.msg=msg try: raise LinuxeaBlog('自己定制的类型错误') except LinuxeaBlog as e: print(e) 直接print print(LinuxeaBlog('自己定制的类型错误'))
八,断言assert
在程序的某个位置,判断是否是自己想要的值,如果不是则会抛出异常,可以用assert也可以用if判断
-
示例:
def linuxea1(): # print('逻辑1') res=1 return res def linuxea2(): # print('逻辑2') res=2 return res a1=linuxea1() a2=linuxea2() assert a1 == 1 print('a1等于1')
linuxea1和linuxea2,在最后assert断言a1等于1。如果assert断言a1等于1条件成立,则执行print('a1等于1'),否则则报错
-
其实可以使用其他方式,如if:
if a1 !=1: raise AssertionError
相比较assert a1 == 1,和if的使用,assert断言是非常简单明了的
九,try except与if判断
在try except和if中都可以被用到,都可以使用。
-
try和except
try: 'code' except TypeError: 其他异常1 '其他逻辑1' except keyError: 其他异常2 '其他逻辑2' except Exception: 其他没有考虑到的异常 '其他逻辑3'
-
单单if
if '条件': 'code' elif '其他条件1': '其他逻辑1' elif '其他条件2': '其他逻辑2' else: 其他没有考虑到的条件 '其他逻辑3'