try finally执行顺序 python_Python学习之路(18)——try except else finally语句块有return时的执行顺序探究...

在Python的异常处理中,基本的结构是如下:

>>> try:

pass

except:

pass

finally:

pass

思路是:

1)先执行try语句块;

2)如果try语句块发生异常,且与except中的异常相同,则执行except语句块;

3)无论是否有异常,最后执行finally语句块。

但是如果在每个语句块中加入return语句,那么执行顺序是如何的呢?

下面看几个列子:

1、不带return语句的情况

print('this is a test of code path in try...except...else...finally')

print('************************************************************')

def exceptTest():

try:

print('doing some work, and maybe exception will be raised')

raise IndexError('index error')

print('after exception raise')

# return 0

except IndexError as e:

print('in IndexError except')

print(e)

# return 1

else:

print('no exception')

# return 2

finally:

print('in finally')

# return 3

resultCode = exceptTest()

print(resultCode)

上面的代码中,将所有return的语句注释掉,执行结果如下:

this is a test of code path in try...except...else...finally

************************************************************

doing some work, and maybe exception will be raised

in IndexError except

index error

in finally

None

2、添加return语句(try语句块中产生异常,匹配到except语句块,跳过else语句块,最后执行finally语句块)

print('this is a test of code path in try...except...else...finally')

print('************************************************************')

def exceptTest():

try:

print('doing some work, and maybe exception will be raised')

raise IndexError('index error')

print('after exception raise')

return 0

except IndexError as e:

print('in IndexError except')

print(e)

return 1

else:

print('no exception')

return 2

finally:

print('in finally')

return 3

resultCode = exceptTest()

print(resultCode)

输出结果为:(finally语句块中的return语句拥有最高优先级输出)

this is a test of code path in try...except...else...finally

************************************************************

doing some work, and maybe exception will be raised

in IndexError except

index error

in finally

3

3、只有finally语句中不添加return语句(try语句块中产生异常,匹配到except语句块,跳过else语句块,最后执行finally语句块):

print('this is a test of code path in try...except...else...finally')

print('************************************************************')

def exceptTest():

try:

print('doing some work, and maybe exception will be raised')

raise IndexError('index error')

print('after exception raise')

return 0

except IndexError as e:

print('in IndexError except')

print(e)

return 1

else:

print('no exception')

return 2

finally:

print('in finally')

# return 3

resultCode = exceptTest()

print(resultCode)

输入结果为:

this is a test of code path in try...except...else...finally

************************************************************

doing some work, and maybe exception will be raised

in IndexError except

index error

in finally

1

此时返回值变为1。

因为有异常发生,try语句中的return没有执行到,然后到捕捉到的except语句块中执行,并且except语句块中存在return语句,而finally语句时必须要执行的,所有except里的return语句先搁置,然后finally执行完后返回到except语句块中执行return,因此最终的返回值为1。

4、finally中不添加return,且try语句块中不产生异常:

print('this is a test of code path in try...except...else...finally')

print('************************************************************')

def exceptTest():

try:

print('doing some work, and maybe exception will be raised')

# raise IndexError('index error')

print('after exception raise')

return 0

except IndexError as e:

print('in IndexError except')

print(e)

return 1

else:

print('no exception')

return 2

finally:

print('in finally')

# return 3

resultCode = exceptTest()

print(resultCode)

执行结果如下:

this is a test of code path in try...except...else...finally

************************************************************

doing some work, and maybe exception will be raised

after exception raise

in finally

0

这里可以看到没有返回else的return值,因为没有异常发生,会执行到try语句块中的return语句,而finally语句块必须执行,所有这里的return语句也搁置,先执行完finally语句块,然后返回到try语句块中的return语句,而try语句块执行了return语句,所以else语句块并没有得到执行。

结论:

1)如果没有异常发生, try中有return 语句, 这个时候else块中的代码是没有办法执行到的, 但是finally语句中如果有return 语句会修改最终的返回值, 我个人理解的是try中return 语句先将要返回的值放在某个 CPU寄存器,然后运行finally语句的时候修改了这个寄存器的值,最后在返回到try中的return语句返回修改后的值。

2.)如果没有异常发生, try中没有return语句,那么else块的代码是执行的,但是如果else中有return, 那么也要先执行finally的代码, 返回值的修改与上面一条一致。

3.)如果有异常发生,try中的return语句肯定是执行不到, 在捕获异常的 except语句中,如果存在return语句,那么也要先执行finally的代码,finally里面的代码会修改最终的返回值,然后在从 except 块的retrun 语句返回最终修改的返回值, 和第一条一致。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值