python throw_python的异常处理

一、异常处理

1、错误Error

逻辑错误:算法写错了

笔误:变量名写错了,语法错误

函数或类的使用错误,其实这也属于逻辑错误,错误是可以避免的

2、异常Exception

本意就是意外情况,这有个前提,没有出现上面说的错误,也就是说程序写的没有问题,但是在某些情况下会出现一些意外,导致程序无法正常执行下去

3、错误和异常

在高级编程语言中,一般都是有错误和异常的概念,异常时可以捕获,并被处理的,但是错误是不能被捕获的

一个健壮的程序因尽可能的避免错误,尽可能的捕获、处理各种异常

二、产生异常

1、产生

raise语句显式的抛出异常,python解释器自己检测到异常并引发它

deffoo():print('before')defbar():print(1/0) #除零异常

bar()print('after')

foo()defbar():print('before')raise Exception('my exextion')print('after')

bar()

程序会在异常抛出的地方中断执行,如果不捕获异常,就会提前结束程序

三、异常的捕获

try:

待捕获异常的代码块except[异常类型]

异常的处理代码块try:print('begin')

c=1/0print('end')except:print('catch the exception')print('outer')

上例执行到c=1/0时产生异常b并抛出,由于使用了try...except语句块则捕获到了这个异常

异常生成位置之后语句将不再执行,转而执行对应的except部分的语句,最后执行try...except语句块之外的语句

四、异常类及继承层次

1、BaseException及子类

所有内建异常类的基类是BaseException

2、SystemExit

sys.exit()函数引发的异常,异常不捕获处理,就直接交给python解释器,解释器退出

举例1:importsysprint('before')

sys.exit(1)print('SysExit')print('outer') #是否执行

举例2:#捕获这个异常

importsystry:

sys.exit(1)exceptSystemExit:print('SysExit')print('outer')

举例3:#对应的捕获用户中断行为Ctrl + c

try:importtimewhileTrue:

time.sleep(0.5)pass

exceptKeyboardInterrupt:print('crtl + c')print('outer')

3、Exception及子类

Exception是所有内建的,非系统退出的异常的基类,自定义异常应该继承自它

举例1:defa():try:

0a= 5

except:pass执行报错:

File"", line 40a= 5

^SyntaxError: invalid syntax

SyntaxError语法错误,python将这种错误也归到异常类下面的Exception下的子类,但是这种错误是不可捕获的

ArithmeticError所有算术计算引发的异常,其子类除零异常等

LookupError:使用映射的键或者序列的索引无效时引发的异常的基类:IndexError,KeyError

4、自定义的异常,从Exception继承的类

classMyException(Exception):pass

try:raiseMyException()except: #捕获自定义异常

print('cathc the exception')

五、异常的捕获

1、except可以捕获多个异常

举例1:classMyException(Exception):pass

try:

a= 1/0raise MyException() #自定义的异常

open('a1.txt')except MyException: #捕获自定义异常

print('cathc the MyException')exceptZeroDivisionError:print('1/0')exceptException:print('Exception')

捕获规则:捕获是从上到下依次比较,如果匹配,则执行匹配的except语句块

如果被一个except语句捕获,其他except语句就不会再次捕获了

如果没有任何一个except捕获到这异常,则该异常向外抛出

捕获原则:从小到大,从具体到宽泛

2、as 字句

被抛出的异常,应该是异常的实例,如何获取得到这个对象,使用as字句

举例1:classMyException(Exception):def __init__(self, code, message):

self.code=code

self.message=messagetry:raiseMyException()#raise MyException(200,'ok') #raise后跟类名是无参构造实例,因此需要2个参数

except MyException as e: #捕获自定义异常

print('MyException = {}{}'.format(e.code, e.message))exceptException as e:print('Exception = {}'.format(e))

执行输出:Exception= __init__() missing 2 required positional arguments: 'code' and 'message'

#执行输出:MyException = 200,ok

3、finally子句

即最后一定要执行的语句,try...finally语句块中,不管是否发生了异常,都要执行finally的部分

举例1:

f=Nonetry:

f= open('test.txt')exceptFileNotFoundError as e:print(e)print('{},{},{}'.format(e.__class__, e.errno, e.strerror))finally:print('清理工作')iff:

f.close()1、finally执行时机

测试1:deffoo():try:return 3

finally:print('finally')print('===========')print(foo())

执行报错:finally

3进入try,执行return3,虽然函数要返回,但是finally一定还要执行,所以打印了finally后,函数返回

测试2:deffoo():try:return 3

finally:return 5

print('===========')print(foo())

进入try,执行return3,虽然函数要返回,但是finally一定要执行,所以执行return 5,

函数返回,5被压在栈顶,所以返回5,简单说,函数的返回值取决于最后一个执行的return语句

而finally则是try...finally中最后执行的语句块

六、异常的传递

举例1:deffoo1():return 1/0deffoo2():print('foo2 start')

foo1()print('foo2 stop')

foo2()

foo2调用了foo1,foo1产出的异常,传递到了foo2中

异常总是向外层抛出,如果外层没有处理这个异常,就会继续向外抛出

如果内层捕获并处理了异常,外部就不能捕获到了

如果到了最外层还是没有被处理,就会中断异常所在的线程的执行

举例2:#线程中测试异常

importthreadingimporttimedeffoo1():return 1/0deffoo2():

time.sleep(3)print('foo2 start')

foo1()print('foo2 stop')

t= threading.Thread(target=foo2)

t.start()whileTrue:

time.sleep(1)print('Everthing OK')ift.is_alive():print('alive')else:print('dead')2、try的嵌套

举例1:try:try:

ret= 1/0exceptKeyError as e:print(e)else:print('inner OK')finally:print('inner fin')except:print('outer catch')finally:print('outer fin')

内部捕获不到异常,会向外层传递异常,但是如果内层有finally且其中有return,break语句,则异常就不会继续向外抛出,异常被丢弃

举例2:deffoo():try:

ret= 1/0exceptKeyError as e:print(e)finally:print('inner fin')return #异常被丢弃

try:

foo()except:print('outer catch')finally:print('outer fin')

七、异常的捕获时机

1、立即捕获

需要立即返回一个明确的结果defparse_int(s):try:returnint(s)except:return0print(parse_int('s'))

2、边界捕获

封装产出了边界

例如,写了一个模块,用户调用这个模块的时候捕获异常,模块内部不需要捕获,处理异常一旦内部处理了,外部调用者就无法感知了

例如open函数,出现的异常交给调用者处理,文件存在了,就不用再创建了,看是否修改还是删除

例如自己写了一个类,使用了open函数,但是出现了异常不知道如何处理,就继续向外层抛出

一般来说最外层也是边界,必须处理这个异常了,否则线程退出

3、else子句

没有任何异常发生,则执行try:

ret= 1/0exceptArithemticError as e:print(e)else:print('OK')finally:print('fin')

总结:try: #运行别的代码

except : #捕获某种类型的异常

except as : #捕获某种类型的异常并获得对象

else: #如果没有异常发生

finally: #退出try时总会执行

八、try的工作原理

如果try中语句执行时发生异常,搜索except子句,并执行第一个匹配该异常的except子句

如果try中语句执行时发生异常,却没有匹配的except子句,异常将被递交到外层的try如果外层不处理这个异常,异常将继续向外层传递,如果都不处理该异常,则会传递到最外层,如果还没有处理,就终止异常所在线程

如果在try执行时没有发生异常,将执行else子句中的语句

无论try中是否发生异常,finally子句最终都会执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值