Python - 异常似乎是跳过了阻塞

时间:2014-06-08 19:05:46

标签: python with-statement contextmanager

以下是相关的代码:

    @contextlib.contextmanager
    def make_temp_dir():
      temp_dir = tempfile.mkdtemp()
      yield temp_dir
      shutil.rmtree(temp_dir)

    with make_temp_dir(listing_id) as tmpdir:
      pass
      # Sometimes something in here throws an exception that gets caught higher up

好的,所以写下这一切,我现在明白发生了什么。我使用装饰器创建的上下文管理器中的退出方法正在运行,但当然不会将流返回到我的生成器。

那么应该如何我这样做呢?

1 个答案:

答案 0 :(得分:0)

这里会发生以下情况:

  • __enter__()上,启动生成器。它的收益率是__enter__()
  • 的返回值
  • __exit__()上,以正常方式或通过注入异常恢复生成器。相关代码位于$PYTHONROOT/contextlib.py,您可以在其中看到生成器上调用了next()throw()

如果在生成器上调用了throw(),则异常会在我们最后一次离开它的地方引发异常,i。即yield表达式会引发异常。

因此,您必须将yield括在try:语句中。只有这样,你才能做出异常的事情。

如果你没有这样做,你的发电机会在没有做任何事情的情况下提起异常。

你可能想要

@contextlib.contextmanager
def make_temp_dir():
    temp_dir = tempfile.mkdtemp()
    try:
        yield temp_dir
    finally:
        shutil.rmtree(temp_dir)