用块内部进行python异常处理

时间:2018-06-06 08:42:27

标签: python python-3.x exception-handling with-statement contextmanager

以下代码是否对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]

1 个答案:

答案 0 :(得分:4)

with语句控制的块内的异常通过generator.throw()传播到您的生成器上下文管理器,如PEP 343: "Generator Decorator"所示,这会在生成器处引发异常停顿了一下。换句话说,你应该将metaData包装在try / except或try / finally中:

yield

引用有关主题的official documentation

  

...如果块中发生未处理的异常,则在生成器发生收益的位置对其进行再加标。因此,您可以使用try ... except ... finally语句来捕获错误(如果有),或确保进行一些清理。如果仅为了记录异常或执行某些操作(而不是完全禁止它)而捕获异常,则生成器必须重新加载该异常。否则,生成器上下文管理器将向with语句指示已处理该异常,并且将在with语句之后立即执行该语句。