Python-Exception似乎正在跳出with块

Python-Exception似乎正在跳出with块,python,with-statement,contextmanager,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 thro

以下是相关代码:

    @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
好的,把这些都写下来,我现在明白发生了什么。我用decorator创建的contextmanager中的exit方法正在运行,但这当然不会将流返回到我的生成器


那么我应该怎么做呢?

这里发生的事情如下:

输入时,发电机启动。它产生的结果将作为返回值uu输入。 在退出时,以正常方式或通过注入异常恢复生成器。相关代码在$PYTHONROOT/contextlib.py中,您可以看到在生成器上调用了next或throw。 如果在生成器上调用了throw,那么异常将在它内部引发,正好是我们上次放置它的位置,即。E然后,yield表达式引发异常

因此,您必须将收益率包含在try:语句中。只有到那时,你才能做一些例外的事情

如果未能执行此操作,则生成器将在不执行任何操作的情况下将异常发回

你可能想要

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

如果希望捕获contextmanager中的异常,则需要像往常一样编写try/except。看,谢谢。所以这个例外在我的发电机里被重新提出,对吗?我想我的意思是,这个异常仍然会由现有的处理,除了我的权限之外?所以它的工作原理就像。。提出了一个例外__调用exit_uu,将异常传递给throw,然后由我的外部except处理异常?Thanks@ShaneH是的,但它不是真正的外部。with语句被映射到生成器中的try…finally。