Python中try except else finally中执行原理

在python中,异常捕捉常用的方法是try…except…方法,其中如果在try…except方法中使用了else以及finally后,异常捕捉的执行逻辑会存在差异

1.try/except使用,执行顺序

def func():
    i = 0
    try:
        i += 1
        print('执行try中逻辑')
        j = i / 0
    except Exception as e:
        print('执行异常中的代码逻辑', e)

func()

执行结果:
执行try中逻辑
执行异常中的代码逻辑 division by zero

在只有try和except的异常捕捉代码中,可以发现先执行try中逻辑,当try中逻辑执行异常后,except捕捉到异常并执行except中代码逻辑。

上面介绍一下try/except异常机制,废话不多说,上干货

2.分析try/except/else/finally中代码执行逻辑

情况一:try/except中全部异常

def func():
    try:
        print('执行try中逻辑')
        j = 10 / 0
    except Exception as e:
        print('执行异常中的代码逻辑', e)
        i = 10 / 0
    else:
        print('执行else中逻辑')
    finally:
        print('执行finally中逻辑')


func()

打印结果:
执行try中逻辑
执行异常中的代码逻辑 division by zero
执行finally中逻辑
Traceback (most recent call last):
  File "D:/work/code/auto_test/m_test.py", line 209, in func
    j = 10 / 0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:/work/code/auto_test/m_test.py", line 219, in <module>
    func()
  File "D:/work/code/auto_test/m_test.py", line 212, in func
    i = 10 / 0
ZeroDivisionError: division by zero

当try和except中同时存在异常时,此时先抛出try中异常,然后再抛出except中异常,但是当我们再finally语句后加一个return,那么重点来了

def func():
    try:
        print('执行try中逻辑')
        j = 10 / 0
    except Exception as e:
        print('执行异常中的代码逻辑', e)
        i = 10 / 0
    else:
        print('执行else中逻辑')
    finally:
        print('执行finally中逻辑')
        return 10

a = func()
print(a)

打印结果为:
执行try中逻辑
执行异常中的代码逻辑 division by zero
执行finally中逻辑
10

当finally中有return时,try/except虽然有异常但是并没有抛出,这是因为在try/except/else/finally逻辑中,finally执行逻辑比try/except异常抛出执行的逻辑要优先,注意是finally执行逻辑比try/except中异常抛出的优先级要高,而不是try/except中非异常代码逻辑的优先级
这也可以从官方文档得到体现
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed. The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement.
大致意思就是:就是说except、else子句中的异常在finally子句执行之后才会抛出,但是finally直接return了,所以我们就看不到异常了,而且会覆盖本身的return值。这种用法显然是不符合初衷的,所以不建议在finally语句中使用return、break、continue这些跳出的语句,应仅用作资源释放操作,否则会出现意想不到的结果

3.try/except/else/finally中else中出现异常,finally中return

def func():
    try:
        print('执行try中逻辑')

    except Exception as e:
        print('执行异常中的代码逻辑', e)
    else:
        j = 10 / 0
        print('执行else中逻辑')
    finally:
        print('执行finally中逻辑')
        return 10


a = func()
print(a)

打印结果:
执行try中逻辑
执行finally中逻辑
10

当else中哟与异常,但是finally中有return时,else的异常没有抛出

4.try/except/else/finally中嵌套使用

def test():
    signal = False
    try:
        k = 11
        result = False
        if k > 10:
            try:
                b = 0
                c = k / b
            except Exception as e:
                print("内层异常,报错信息如下 %s" % e)
                return 'inner'
        else:
            pass
        print("执行内层其他逻辑")
        n = 1/0

    except Exception as e:
        print("外层异常报错")
    else:
        print("执行else逻辑")
    finally:
        return signal


mm = test()
print(mm)

打印的结果为:
内层异常,报错信息如下 division by zero
False

虽然内层异常中有return返回, 因为外层finally中有return,会覆盖内层的return,所以最终输出的结果为finally的返回值

综上所述:
1.执行顺序 finally > return > else(finally大于return是finally中执行逻辑会比try,except,else中return返回的逻辑要优先执行)
2.finally的return会抑制其他子句异常抛出,不建议使用

猜你喜欢

转载自blog.csdn.net/qq_42707967/article/details/109528671
今日推荐