首页 文章

如何在Python中使用“with open”打开多个文件?

提问于
浏览
499

我想一次更改几个文件, iff 我可以写给所有文件 . 我想知道我是否能以某种方式将多个打开调用与 with 语句组合在一起:

try:
  with open('a', 'w') as a and open('b', 'w') as b:
    do_something()
except IOError as e:
  print 'Operation failed: %s' % e.strerror

如果那是不可能的,那么这个问题的优雅解决方案会是什么样子?

6 回答

  • 87

    从Python 2.7(或分别为3.1)开始,您可以编写

    with open('a', 'w') as a, open('b', 'w') as b:
        do_something()
    

    在早期版本的Python中,您有时可以使用contextlib.nested()来嵌套上下文管理器 . 但是,这对于打开多个文件不起作用 - 请参阅链接文档以获取详细信息 .

  • 772

    只需将 and 替换为 , 即可完成:

    try:
        with open('a', 'w') as a, open('b', 'w') as b:
            do_something()
    except IOError as e:
        print 'Operation failed: %s' % e.strerror
    
  • 41

    要一次打开多个文件或长文件路径,在多行中分解可能很有用 . 从@Sven Marnach所建议的Python Style Guide评论到另一个答案:

    with open('/path/to/InFile.ext', 'r') as file_1, \
         open('/path/to/OutFile.ext', 'w') as file_2:
        file_2.write(file_1.read())
    
  • 0

    嵌套语句将完成相同的工作,在我看来,更直接的处理 .

    假设您有inFile.txt,并希望同时将其写入两个outFile .

    with open("inFile.txt", 'r') as fr:
        with open("outFile1.txt", 'w') as fw1:
            with open("outFile2.txt", 'w') as fw2:
                for line in fr.readlines():
                    fw1.writelines(line)
                    fw2.writelines(line)
    

    编辑:

    我不明白downvote的原因 . 我在发布我的答案之前测试了我的代码,并且它按照需要工作:它写入所有outFile,就像问题一样 . 没有重复写或无法写 . 所以我很想知道为什么我的答案被认为是错误的,次优的或类似的 .

  • 8

    使用python 2.6它将无法正常工作,我们必须使用以下方式打开多个文件:

    with open('a', 'w') as a:
        with open('b', 'w') as b:
    
  • 3

    从Python 3.3开始,您可以安全地使用contextlib模块中的类ExitStack
    open an arbitrary number of files .

    它可以管理动态数量的上下文感知对象,这意味着如果您不知道要处理多少文件,它将特别有用 .

    实际上,文档中提到的规范用例是管理动态数量的文件 .

    with ExitStack() as stack:
        files = [stack.enter_context(open(fname)) for fname in filenames]
        # All opened files will automatically be closed at the end of
        # the with statement, even if attempts to open files later
        # in the list raise an exception
    

    如果您对详细信息感兴趣,以下是一个通用示例,以解释 ExitStack 如何运作:

    from contextlib import ExitStack
    
    class X:
        num = 1
    
        def __init__(self):
            self.num = X.num
            X.num += 1
    
        def __repr__(self):
            cls = type(self)
            return '{cls.__name__}{self.num}'.format(cls=cls, self=self)
    
        def __enter__(self):
            print('enter {!r}'.format(self))
            return self.num
    
        def __exit__(self, exc_type, exc_value, traceback):
            print('exit {!r}'.format(self))
            return True
    
    xs = [X() for _ in range(3)]
    
    with ExitStack() as stack:
        print(len(stack._exit_callbacks)) # number of callbacks called on exit
        nums = [stack.enter_context(x) for x in xs]
        print(len(stack._exit_callbacks))
    
    print(len(stack._exit_callbacks))
    print(nums)
    

    输出:

    0
    enter X1
    enter X2
    enter X3
    3
    exit X3
    exit X2
    exit X1
    0
    [1, 2, 3]
    

相关问题