有没有一种有意义的方法可以在生成器中使用上下文管理器?

发布于 2024-11-10 14:40:26 字数 566 浏览 3 评论 0原文

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

输出:

entering

有没有办法让Python在for循环中断时自动调用context()的__exit__方法?或者通过其他方式实现相同的目标?我对生成器和上下文管理器的了解让我怀疑这是不可能的,但这使得上下文管理器在生成器中毫无用处,不是吗?在我看来,with块内的yield语句应该引发一个红旗,上下文管理器__exit__可能无法运行。

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

output:

entering

Is there a way to make python automatically invoke the __exit__ method of context() when the for-loop is interrupted? Or some other way of achieving the same aim? What I know about generators and context managers makes me suspect it's not possible, but this makes context managers rather useless inside generators, doesn't it? It seems to me, a yield statement inside a with block should raise a red flag, context manager __exit__ may not run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风筝有风,海豚有海 2024-11-17 14:40:27

好吧,您可以使用 try/finally 子句将yield 包装在 context() 函数中:

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

输出:

entering
exiting

编辑: 如果您尝试:help(contextmanager),它将显示这是“典型”的用法示例,其中他们用 try/finally 子句包装了收益。

Well, you could wrap the yield in context() function with a try/finally clause:

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

output:

entering
exiting

Edit: If you try a: help(contextmanager), it will show it's "typical" useage example where they wrap the yield with a try/finally clause.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文