麻烦帮忙看看这道简单的题,为什么 finally 会被执行两次呢?

2017-07-08 10:06:27 +08:00
 gap
def fancy_divide(numbers, index):
    try:
        denom = numbers[index]
        for i in range(len(numbers)):
            numbers[i] /= denom
    except IndexError:
        fancy_divide(numbers, len(numbers) - 1)
    except ZeroDivisionError:
        print("-2")
    else:
        print("1")
    finally:
        print("0")

fancy_divide([0, 2, 4], 4)

结果是1 0 01 0我理解,但为什么最后还有个 0 呢?finally被执行两次?

2816 次点击
所在节点    Python
8 条回复
Herobs
2017-07-08 10:13:53 +08:00
递归完了才会执行第一次的 finally
mianju
2017-07-08 10:15:14 +08:00
你第一次触发了 IndexError,在处理完 IndexError 异常后是会调用 finally,加上 fancy_divide(numbers, len(numbers) - 1)里执行的 finally,总共两次 finally 没问题呀。
mianju
2017-07-08 10:15:38 +08:00
其实打个断点就能知道了
Herobs
2017-07-08 10:15:50 +08:00
或者这么理解,finally 一定会执行,你这个函数调用了两次,那肯定会执行两次。
zjuhwc
2017-07-08 10:17:55 +08:00
第一次执行触发 indexerror,然后再递归执行一次,第二次正常执行,打印 else 里的 1,打印 finally 里的 0,然后回到第一次执行的函数里,打印 finally 里的 0。

finally 的含义是不管函数是否抛出异常都会执行。

另外,建议这种问题用单步调试来看每一步执行过程,比较容易理解
icenan2
2017-07-08 10:20:31 +08:00
递归啊,1 0 都理解,最后的 0 更好理解了嘛
gap
2017-07-08 10:25:13 +08:00
原来如此,感谢大家!
suueyoung
2017-07-08 11:37:51 +08:00
递归里面还是 call 了一遍 finally

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/373881

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX