python try except continue_python中 try、except、finally执行顺序

我们虽然经常用到try...except 作为异常补货,但是其实很少去研究try源码和机制,也许点进去看过,也是看不出个所以然来

classException(BaseException):"""Common base class for all non-exit exceptions."""

def __init__(self, *args, **kwargs): #real signature unknown

pass

继承了BaseException

classBaseException(object):"""Common base class for all exceptions"""

def with_traceback(self, tb): #real signature unknown; restored from __doc__

"""Exception.with_traceback(tb) --

set self.__traceback__ to tb and return self."""

pass

def __delattr__(self, *args, **kwargs): #real signature unknown

"""Implement delattr(self, name)."""

pass

def __getattribute__(self, *args, **kwargs): #real signature unknown

"""Return getattr(self, name)."""

pass

def __init__(self, *args, **kwargs): #real signature unknown

pass..................

是不是仍然一脸懵逼,同感,哈哈,那还是直接上代码,事实大于雄辩

代码举例转自https://blog.csdn.net/u010159842/article/details/54924940 我觉得这个作者写的很清楚

一:在 try 中 raise一个异常,就立刻转入 except 中执行,在except 中遇到 return 时,就强制转到 finally 中执行, 在 finally 中遇到 return 时就返回,最终函数返回值是finally 返回的

ef test1():try:print('to do stuff')raise Exception('hehe')print('to return in try')return 'try'

exceptException:print('process except')return 'except'

finally:print('to return in finally')return 'finally'test1Return=test1()print('test1Return :' +test1Return)#输出:

#to do stuff#process except#to return in finally#test1Return : finally

二:这里在 try 中没有抛出异常,因此不会转到 except 中,但是在try 中遇到return时,也会立即强制转到finally中执行,并在finally中返回

deftest2():try:print('to do stuff')print('to return in try')return 'try'

exceptException:print('process except')print('to return in except')return 'except'

finally:print('to return in finally')return 'finally'test2Return=test2()print('test1Return :' +test2Return)#输出:#to do stuff#to return in try#to return in finally#test2Return : finally

test1和test2得到的结论:

无论是在try还是在except中,遇到return时,只要设定了finally语句,就会中断当前的return语句,跳转到finally中执行,如果finally中遇到return语句,就直接返回,不再跳转回try/excpet中被中断的return语句

deftest3():

i=0try:

i+= 1

print('i in try : %s'%i)raise Exception('hehe')exceptException:

i+= 1

print('i in except : %s'%i)returnifinally:

i+= 1

print ('i in finally : %s'%i )print('test3Return : %s'%test3())#输出:

#i in try : 1#i in except : 2#i in finally : 3#test3Return : 2

deftest4():

i=0try:

i+= 1

returnifinally:

i+= 1

print ('i in finally : %s'%i )print('test4Return : %s' %test4())#输出#i in finally : 2#test4Return : 1

test3和test4得到的结论:

在except和try中遇到return时,会锁定return的值,然后跳转到finally中,如果finally中没有return语句,则finally执行完毕之后仍返回原return点,将之前锁定的值返回(即finally中的动作不影响返回值),如果finally中有return语句,则执行finally中的return语句。

四:test5得到的结论:在一个循环中,最终要跳出循环之前,会先转到finally执行,执行完毕之后才开始下一轮循环

ContractedBlock.gif

ExpandedBlockStart.gif

deftest5():for i in range(5):try:print('do stuff %s'%i)raiseException(i)exceptException:print('exception %s'%i)continue

finally:print('do finally %s'%i)

test5()

输出

do stuff 0

exception 0

dofinally0

do stuff1exception1dofinally 1do stuff2exception2dofinally 2do stuff3exception3dofinally 3do stuff4exception4dofinally 4

View Code

注:

python的错误也是class,所有的错误类型都继承自BaseException,各个类型的错误之间可能会存在继承关系,比如UnicodeError是ValueError的子类,

如果catch语句中同时出现了这两个错误,且UnicodeError在ValueError的后面处理的,那么永远都捕获不到UnicodeError。

python中内置的常用错误类型继承关系:

使用try…excetp捕获错误一个好处是,可以跨层调用,比如main()调用foo(),foo()调用bar(),而错误是在bar中出现的,最后我们只需要在main()中捕获就行。

五:举个工作中的例子

#首先下面的代码是一段有问题的代码哦,是对try机制了解不清晰

importtimedefpushMsg(ss):try:

res=10/ss #设置报错点

ifres:returnresexceptException as e:returnFalse#该函数需求是调用pushMsg()函数,默认三次不成功返回,就不再调用

defexceptTest(ss):

cnt= 1

while cnt <= 3:try:

res=pushMsg(ss)print("res:",res)ifres:break #如果正常返回了,退出循环

exceptException as e:print(e)continue #本意收集

finally:

cnt+= 1time.sleep(1)print("cnt",cnt)if cnt > 3:print("3 times push failed!")returnTrue#分两种情况(主要考量except和finall,在两层套用情况下执行顺序,也就是内层函数也用了try ,并且return False)#第一种:程序正常走下来,不设置错误 ss传值非零

ss=1exceptTest(ss)#打印执行顺序:只有 res: 10.0,因为内外两层try ,都没有捕获到错误,except和finally 里面都没有执行打印,并且判断res有值就直接break退出循环了

#第二种情况,置报错 ss传值为零

ss=0

exceptTest(ss)#打印执行顺序:下面的顺序,先打印了finally里面的内容,再打印了返回值res,但是!为什么except里面的东西没有打印呢!

"""cnt 2

res: False

cnt 2

res: False

cnt 3

res: False

cnt 4

3 times push failed!"""

#总结上面两种情况,无论是有无异常,except里面的东西都没有执行,那外层的try根本没有用呀,这是为什么呢!#经过研究,发现内层函数pushMsg(ss),也用了try ,但是他直接return True或者False ,并没有把内层捕获到的错误传到外层,所以外层的try也就捕获不到异常了,y#外层函数就会默认没有错误,直接执行finally里面的内容

那么代码就可以这么改

defpushMsg(ss):try:

res=10/ss #设置报错点

ifres:returnresexceptException as e:importtraceback

traceback.print_exc()returnFalsedefexceptTest(ss):

cnt= 1

while cnt <= 3:

res=pushMsg(ss)print("res:", res)ifres:break

else:

cnt+= 1time.sleep(1)if cnt > 3:print("3 times push failed!")return True

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值