Python异常捕捉try except else finally有return时执行顺序探究

在没有return的情况下

try:
#尝试执行的代码
[except 错误类型1 :
#针对错误类型1,对应的代码处理]
[except 错误类型2 :
#针对错误类型2,对应的代码处理]
[except (错误类型3,错误类型4):
#针对错误类型3和4,对应的代码处理]
[except Exception as result:
#打印错误信息]
[else:
#没有异常才会执行的代码]
[finally:
#无论是否有异常,都会执行的代码]

在有return的情况下

Python-try except else 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 KeyError, e:
        print 'in KeyError except'
        print e
        #return 1
    except IndexError, e:
        print 'in IndexError except'
        print e
        #return 2
    except ZeroDivisionError, e:
        print 'in ZeroDivisionError'
        print e
        #return 3
    else:
        print 'no exception'
        #return 4
    finally:
        print 'in finally'
        #return 5
 
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
None

然后我们逐渐给上面代码各个情况添加return 语句, 查看添加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 KeyError, e:
        print 'in KeyError except'
        print e
        return 1
    except IndexError, e:
        print 'in IndexError except'
        print e
        return 2
    except ZeroDivisionError, e:
        print 'in ZeroDivisionError'
        print e
        return 3
    else:
        print 'no exception'
        return 4
    finally:
        print 'in finally'
        return 5
 
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
5

异常发生后,raise语句以后的不再执行,然后到了捕获异常语句, 但是捕获异常模块有个return , 是不是这个时候就不再继续执行直接返回呢?但是这是跟 finally语句必然执行是相冲突的, 可以在结果中看到finally实际上执行了,并且返回值是5。

  1. 注释掉finally 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 KeyError, e:
        print 'in KeyError except'
        print e
        return 1
    except IndexError, e:
        print 'in IndexError except'
        print e
        return 2
    except ZeroDivisionError, e:
        print 'in ZeroDivisionError'
        print e
        return 3
    else:
        print 'no exception'
        return 4
    finally:
        print 'in finally'
        #return 5
 
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
2
  1. 没有异常发生且try语句块没有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 KeyError, e:
        print 'in KeyError except'
        print e
        return 1
    except IndexError, e:
        print 'in IndexError except'
        print e
        return 2
    except ZeroDivisionError, e:
        print 'in ZeroDivisionError'
        print e
        return 3
    else:
        print 'no exception'
        return 4
    finally:
        print 'in finally'
        return 5
 
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
no exception
in finally
5
  1. 没有异常发生且try语句块 存在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 KeyError, e:
        print 'in KeyError except'
        print e
        return 1
    except IndexError, e:
        print 'in IndexError except'
        print e
        return 2
    except ZeroDivisionError, e:
        print 'in ZeroDivisionError'
        print e
        return 3
    else:
        print 'no exception'
        return 4
    finally:
        print 'in finally'
        return 5
 
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
5

分析: 这里因为没有发生异常, 所以会执行到try块中的return 语句,但是finally又必须执行,所以执行try中return 之前去执行了finally语句,并且可以认为,finally语句修改了最后返回的值,将try中的返回值修改为5并最终返回,所以else语句并没有 得到执行。

  1. 有异常发生并且finally 没有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 KeyError, e:
        print 'in KeyError except'
        print e
        return 1
    except IndexError, e:
        print 'in IndexError except'
        print e
        return 2
    except ZeroDivisionError, e:
        print 'in ZeroDivisionError'
        print e
        return 3
    else:
        print 'no exception'
        return 4
    finally:
        print 'in finally'
        #return 5
 
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
2

因为有异常发生,所以try中的return语句肯定是执行不到的,然后在捕获到的except中进行执行,并且except中存在return 语句,那么是不是就直接返回? 因为finally 语句是必须要执行的,所以这里的return语句需要先暂且放下,进入finally进行执行,然后finnaly执行完以后再返回到 except中进行执行。

总结:

  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 语句返回最终修改的返回值, 和第一条一致。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值