0

以下是相关的代码:

    @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

好的,所以把这一切都写出来,我现在明白发生了什么。我用装饰器创建的 contextmanager 中的exit方法正在运行,但是这当然不会将流返回到我的生成器。

那么我应该怎么做呢?

4

1 回答 1

0

这里发生的情况如下:

  • On __enter__(),发电机启动。它产生的值被用作 的返回值__enter__()
  • On __exit__(),以正常方式或通过注入异常来恢复生成器。相关代码在$PYTHONROOT/contextlib.py您可以看到或者next()throw()生成器上被调用的地方。

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

因此,您必须将 附在声明中yieldtry:只有这样,你才能做一些例外的事情。

如果你不这样做,你的生成器将在不做任何事情的情况下引发异常。

你可能想要

@contextlib.contextmanager
def make_temp_dir():
    temp_dir = tempfile.mkdtemp()
    try:
        yield temp_dir
    finally:
        shutil.rmtree(temp_dir)
于 2014-06-08T19:17:07.763 回答