使用finally语句与不使用finally语句的差异及OpenCV帧循环场景下的选型咨询
先来说你给出的两个示例代码的核心差异——finally块的执行是绝对有保障的,而直接放在try/except后面的代码不一定。
看你提供的Code 1和Code 2,在当前的ZeroDivisionError场景下,两者的输出确实一样:都会先打印错误信息,再打印"Finishing up."。但如果换一种情况,比如try块里的代码抛出了一个不在except块捕获范围内的异常,或者try/except里有return、break这类会提前终止代码的语句,差异就显现了:
举个例子,假设把Code 2改成这样:
a = 10 b = 0 try: c = a / b print(c) return # 这里加个提前终止的return except ZeroDivisionError as error: print(error) print('Finishing up.')
这时候"Finishing up."就不会被执行,因为try块里的return会直接终止函数。但如果用finally块,不管try里有没有return,也不管异常有没有被except捕获,finally里的代码一定会跑。
至于性能?完全不用担心,finally几乎没有性能开销,Python对它的处理和普通代码块没什么区别,这点可以忽略不计。
再回到你的OpenCV帧循环场景,我建议你必须用finally块来读取下一帧。为什么?
你当前的代码里,try块包含了写视频帧、推理等多个操作,这些环节都有可能抛出各种没被except捕获的异常(比如某个推理函数抛出了自定义异常,或者视频写入时突然失败)。如果不用finally,一旦出现这种未捕获的异常,ret, frame = capture.read()这行代码就不会执行,你的循环会直接中断,而不是正常读取下一帧继续处理。
用finally的话,不管try块里成功执行、抛出了被捕获的异常,还是抛出了未被捕获的异常,读取下一帧的操作都会执行,这样你的循环才能保持正常的流程,不会因为一次意外错误就直接停掉,稳定性会高很多。
总结一下:
finally的核心价值是保证代码块必执行,这是普通代码做不到的- 性能差异可以忽略不计
- 在你的OpenCV帧循环场景里,强烈建议用
finally来处理读取下一帧的逻辑
备注:内容来源于stack exchange,提问作者Muhammad Ikhwan Perwira

