【发布时间】:2016-12-22 08:31:09
【问题描述】:
PyCharm 对这段代码发出警告,说最后一个返回是不可达的:
def foo():
with open(...):
return 1
return 0
如果open() 失败,我希望执行第二次返回。谁是对的?
【问题讨论】:
标签: python pycharm with-statement contextmanager
PyCharm 对这段代码发出警告,说最后一个返回是不可达的:
def foo():
with open(...):
return 1
return 0
如果open() 失败,我希望执行第二次返回。谁是对的?
【问题讨论】:
标签: python pycharm with-statement contextmanager
PyCharm 是对的。如果open() 失败,则会引发异常,并且两者都到达return。
with 不会以某种方式保护您免受生成上下文管理器的表达式中的异常的影响。 with 之后的表达式预计会产生一个上下文管理器,此时它的__exit__ 方法被存储并调用它的__enter__ 方法。这里唯一的结果是上下文管理器成功生成并进入,或者引发异常。 with 在此阶段绝不会吞下异常并默默地跳过该块。
【讨论】:
open() 是一个函数调用,调用的结果是一个上下文管理器。该调用可能会产生异常而不是返回某些内容。这就是这里的问题;在创建上下文管理器之前,仍然可能发生异常。
open() 替换为总是 返回上下文管理器且从不引发异常的东西,那么您可以强制解决问题。但是如果你的替换仍然打开一个文件对象,你仍然需要在那个阶段处理异常。