Python 是否有一种在生成器中使用上下文管理器的有意义的方法?

Python 是否有一种在生成器中使用上下文管理器的有意义的方法?,python,generator,contextmanager,Python,Generator,Contextmanager,输出: from contextlib import contextmanager @contextmanager def context(): print "entering" yield print "exiting" def test(): with context(): for x in range(10): yield x for x in test(): if x == 5: bre

输出:

from contextlib import contextmanager

@contextmanager
def context():
    print "entering"
    yield
    print "exiting"

def test():
    with context():
        for x in range(10):
            yield x

for x in test():
    if x == 5:
        break  # or raise
from contextlib import contextmanager

@contextmanager
def context():
    print "entering"
    try:
        yield
    finally:
        print "exiting"

def test():
    with context():
        for x in range(10):
            yield x

for x in test():
    if x == 5:
        break  # or raise

for
-循环被中断时,有没有办法让python自动调用context()的
退出方法?还是以其他方式实现同样的目标?我对生成器和上下文管理器的了解让我怀疑这是不可能的,但这使得上下文管理器在生成器中相当无用,不是吗?在我看来,带有
块的
中的
yield
语句应该会发出一个红旗,上下文管理器
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

entering
输出:

from contextlib import contextmanager

@contextmanager
def context():
    print "entering"
    yield
    print "exiting"

def test():
    with context():
        for x in range(10):
            yield x

for x in test():
    if x == 5:
        break  # or raise
from contextlib import contextmanager

@contextmanager
def context():
    print "entering"
    try:
        yield
    finally:
        print "exiting"

def test():
    with context():
        for x in range(10):
            yield x

for x in test():
    if x == 5:
        break  # or raise

编辑:如果您尝试一个:帮助(contextmanager),它将显示一个“典型”的使用示例,其中他们用try/finally子句包装收益。

这正是您应该做的:在循环
test()
被删除后,在
收益x
处引发
GeneratorExit()
。这反过来又打破了
和:for:
块。然后contextmanager再次捕获
GeneratorExit()
,并在
上下文中以收益率提升它-这就是您必须捕获它的地方,否则
上下文就在那里结束(毕竟它也是一个生成器,所以此异常会以静默方式结束),而不进行清理。文档声明:“因此,您可以使用try…except…finally语句来捕获错误(如果有),或者确保进行一些清理”