首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在生成器中使用上下文管理器会导致资源泄漏吗?

在生成器中使用上下文管理器会导致资源泄漏吗?
EN

Stack Overflow用户
提问于 2019-11-21 12:06:31
回答 1查看 397关注 0票数 3

我有一个从上下文管理器生成的函数:

代码语言:javascript
复制
def producer(pathname):
    with open(pathname) as f:
        while True:
            chunk = f.read(4)
            if not chunk:
               break
            yield chunk

当生成器完全被消耗时,这并不是一个问题,因为在上一次迭代期间,生成器在收益率语句之后恢复执行,循环中断,我们很好地退出上下文管理器。

然而,如果发电机只被部分消耗,并且没有更多的消费者完全使用它,那么生成器会永远暂停吗?在这种情况下,我们永远不会退出上下文管理器。这是否意味着文件将在其余的程序执行过程中保持打开状态?或者至少在发电机被收集垃圾之前?这是我应该自己处理的一个角落情况,还是我可以依靠Python运行时来及时关闭悬空的上下文管理器?

FWIW,我见过Generator and context manager at the same timeHow to use a python context manager inside a generator,但我不认为他们真的回答了同样的问题。除非我漏掉了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-04 04:32:00

如果无法使用整个生成器,则在垃圾收集生成器之前不会清除上下文管理器,如果涉及引用周期,或者在非CPython解释器上运行,这可能需要相当长的时间。

您可以通过生成器迭代器close-ing来解决这个问题;所有生成器函数都在生成的生成器迭代器上提供a close method,生成迭代器在其中引发GeneratorExitwith语句中的异常气泡等等,以确保正确地清除它们。

要使其发生在保证的时间点上,您可以通过use contextlib.closing获得生成器本身的保证关闭:

代码语言:javascript
复制
 from contextlib import closing

 with closing(producer(mypath)) as produced_items:
     for item in produced_items:
         # Do stuff, maybe break loop early

即使您breakreturn或引发异常,with控制produced_items也会对其进行close,这反过来将调用对其中的with语句的清理。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58974675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档