以下代码是否对python3的with
语句和异常处理有任何错误?如果不是,编写我的预期输出的正确方法是什么?
from contextlib import contextmanager
@contextmanager
def test():
print("Hello")
yield
print("goodbye")
try:
with test():
print("inside test")
raise KeyError
except KeyError:
print("KeyError")
else:
print("else")
finally:
print("finally")
,输出
Hello
inside test
KeyError
finally
我期待输出为:
Hello
inside test
goodbye
KeyError
finally
我认为other people写得类似,希望在处理文件期间引发异常时文件会被关闭。
我的python3版本是:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.version)
3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609]
答案 0 :(得分:4)
由with语句控制的块内的异常通过generator.throw()
传播到您的生成器上下文管理器,如PEP 343: "Generator Decorator"所示,这会在生成器处引发异常停顿了一下。换句话说,你应该将metaData
包装在try / except或try / finally中:
yield
引用有关主题的official documentation:
...如果块中发生未处理的异常,则在生成器发生收益的位置对其进行再加标。因此,您可以使用try ... except ... finally语句来捕获错误(如果有),或确保进行一些清理。如果仅为了记录异常或执行某些操作(而不是完全禁止它)而捕获异常,则生成器必须重新加载该异常。否则,生成器上下文管理器将向with语句指示已处理该异常,并且将在with语句之后立即执行该语句。