Python“with”语句堆积

时间:2014-05-28 15:59:00

标签: python with-statement contextmanager

我倾向于经常使用Python“with”语句。在我将一些文件符号链接或复制到目录后,主要用于清理目录,因为即使python脚本崩溃,任务仍会执行。以下是我的函数的示例,可以与“with”语句一起使用。

@contextmanager
def use_symlink(orig, dest):
    os.symlink(orig, dest)
    try: 
        yield
    finally:
        os.unlink(link)

我使用这些语句的方式很快就会堆积起来。

#Off to an adventure
with use_symlink(a, b):
    with use_symlink(c, b):
        with use_symlink(d, b):
            with working_dir(dir1):
                #do something
            with working_dir(dir2):
                #do something that creates file dir2_file1, dir2_file2
                with use_symlink(dir2_file1, b):
                   with use_symlink(dir2_file2, b):
                       with working_dir(b):
                           #Do the last thing
#Home safely

有没有更好的方法来执行上述操作,同时使用强大的“with”语句同样轻松和安全?

1 个答案:

答案 0 :(得分:5)

您可以将多个上下文管理器置于同一with语句下:

with use_symlink(a, b), use_symlink(c, b), use_symlink(d, b):
    with working_dir(dir1):
        #do something
    with working_dir(dir2):
        #do something that creates file dir2_file1, dir2_file2
        with use_symlink(dir2_file1, b), use_symlink(dir2_file2, b), working_dir(b):
            #Do the last thing

在Python 3上,您可以使用contextlib.ExitStack()来管理多个上下文管理器:

from contextlib import ExitStack

with ExitStack() as stack:
    for combo in ((a, b), (c, b), (d, b)):
        stack.enter_context(use_symlink(*combo))
    with working_dir(dir1):
        # do something
    with working_dir(dir2):
        #do something that creates file dir2_file1, dir2_file2
        for combo in ((dir2_file1, b), (dir2_file2, b)):
            stack.enter_context(use_symlink(*combo))
        with working_dir(b):
            #Do the last thing

use_symlink退出时,ExitStack()上下文管理器会以相反的顺序拆除。