首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么生成器不是上下文管理器?

为什么生成器不是上下文管理器?
EN

Stack Overflow用户
提问于 2014-06-03 17:41:44
回答 2查看 498关注 0票数 2

生成器可以通过上下文管理器内部的yield‘管理资源来管理资源。一旦调用生成器的close()方法(或引发异常),资源就会被释放。

由于最后忘记调用close()很容易,我认为显然也要使用上下文管理器(以及处理潜在的异常)。我知道我可以使用contextlib.closing,但是直接在with语句中使用生成器不是更好吗?

为什么生成器不应该是上下文管理器?

EN

回答 2

Stack Overflow用户

发布于 2014-06-03 18:05:13

一般来说,你没有看到更多的生成器作为上下文管理器,而visa相反的原因是,它们的目标是解决不同的问题。上下文管理器之所以出现,是因为它为资源提供了一种简洁的定义可执行代码范围的方法。

有一个非常好的理由,您可能希望将实现__iter__()的类与作为上下文管理器的类分离,这就是单一责任原则。单一责任归结为概念。

做一门课,做一件事,把它做好

列表是可迭代的,但这是因为它们是一个集合。他们只管理他们持有的状态,迭代只是访问该状态的另一种方式。除非您需要迭代作为访问包含对象的状态的一种方法,否则我看不到将两者混合和匹配的理由。即使那样,我也会不遗余力地用真正的OO风格把它分开。

票数 5
EN

Stack Overflow用户

发布于 2014-06-03 19:20:26

就像Wheaties说的,你想让课程只做“一件事,并且做得好”。特别是在上下文管理器中,他们正在管理上下文。所以问问你自己,这里的背景是什么?大多数情况下,它将拥有一个开放的资源。不久前,我询问了using a queue with a context manager的情况,响应基本上是,队列作为上下文没有意义。然而,“在一个任务中”是我所处的真正的上下文,为此做一个上下文管理器是有意义的。

此外,没有迭代的with语句。例如,我不能在这样的语句中打开文件并遍历它:

代码语言:javascript
复制
for line in file with open(filename) as file:
    ...

必须分两行进行:

代码语言:javascript
复制
with open(filename) as file:
    for line in file:
        ...

这很好,因为所管理的上下文不是“我们正在迭代文件”,而是“我们打开了一个文件”。那么,上下文又是什么呢?你到底在做什么?最有可能的是,您的托管上下文实际上不是通过资源进行的迭代。但是,如果您查看特定的问题,您可能会发现确实存在生成器正在管理上下文的情况。希望了解上下文是什么,应该给您一些关于如何适当管理它的想法。

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

https://stackoverflow.com/questions/24021648

复制
相关文章

相似问题

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