我尝试使用控制访问子目录的上下文管理器,将它与生成器表达式结合起来似乎非常优雅,但它似乎不起作用。有没有办法纠正这个,所以我可以一起使用这两个?
以下是例子:
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
答案 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
行的一部分更容易理解。