Python上下文管理器可以用于生成器吗?

时间:2014-12-02 19:05:50

标签: python generator contextmanager generator-expression

我尝试使用控制访问子目录的上下文管理器,将它与生成器表达式结合起来似乎非常优雅,但它似乎不起作用。有没有办法纠正这个,所以我可以一起使用这两个?

以下是例子:

import os, sys
from contextlib import contextmanager
from glob import glob

@contextmanager
def visitDir(d):
    os.chdir(d)
    yield d
    os.chdir("..")

paths = [os.path.join('.', p[0:-1]) for p in glob('*/')]

def clean():
    for p in (visitDir(p) for p in paths): # This is the magic line
        print p
        print os.getcwd()

clean() # Context manager apparently expires within the generator expression

1 个答案:

答案 0 :(得分:2)

您需要控制上下文的进入和离开。生成器表达式没有更广泛的上下文的概念,因此您不能只将上下文管理器放在生成器表达式中,并期望在生成时自动输入。

只有with语句管理实际上下文,触发CM上的__enter____exit__挂钩。您可以在此处使用生成器上下文管理器对象:

def clean():
    for cm in (visitDir(p) for p in paths):
        with cm as p:
            print p
            print os.getcwd()

with语句在此处调用cm.__enter__,并在块完成时调用cm.__exit__

但我发现以下内容更具可读性和易懂性:

def clean():
    for p in paths:
        with visitDir(p):
            print p
            print os.getcwd()

因为创建上下文管理器作为with行的一部分更容易理解。