如何使用“ with with with open”语句打开多个文件(未知的文件数量)?

问题描述 投票:0回答:3
我需要使用

with open

语句打开文件,因为我需要一起打开几百个文件并使用k-way Merge合并它们。
因此,在这一点上,我需要非常快速的I/O,它不会将整个/大部分文件存储在内存中(因为有数百个文件,每个文件中的每个文件)。我只需要一次阅读一行以进行K-Way合并。减少内存使用是我目前的主要重点。

我了解到

with open

是最有效的技术,但是我无法理解如何在单个

open

语句中一起
with open
一起
contextmanager
with

python file python-2.7 merge with-statement
3个回答
5
投票

文档所说的,它很容易编写自己的上下文管理器来处理此操作,以定义“from contextlib import contextmanager @contextmanager def multi_file_manager(files, mode='rt'): """ Open multiple files and make sure they all get closed. """ files = [open(file, mode) for file in files] yield files for file in files: file.close() if __name__ == '__main__': filenames = 'file1', 'file2', 'file3' with multi_file_manager(filenames) as files: a = files[0].readline() b = files[2].readline() ...

语句上下文管理器的出厂功能”。例如:
contextlib.ContextDecorator

如果您不提前知道所有文件,那么创建一个支持它们在上下文中逐步添加它们的上下文管理器同样容易。在下面的代码中,A
MultiFileManager

用作基类来简化from contextlib import ContextDecorator class MultiFileManager(ContextDecorator): def __init__(self, files=None): self.files = [] if files is None else files def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): for file in self.files: file.close() def __iadd__(self, other): """Add file to be closed when leaving context.""" self.files.append(other) return self if __name__ == '__main__': filenames = 'mfm_file1.txt', 'mfm_file2.txt', 'mfm_file3.txt' with MultiFileManager() as mfmgr: for count, filename in enumerate(filenames, start=1): file = open(filename, 'w') mfmgr += file # Add file to be closed later. file.write(f'this is file {count}\n')

类的实现。
contextlib.ExitStack

尽管不是2.7的解决方案,但我应该注意到3.3+的一个好的,正确的解决方案,可用于执行此操作。很好:
from contextlib import ExitStack

with open('source_dataset.txt') as src_file, ExitStack() as stack:
    files = [stack.enter_context(open(fname, 'w')) for fname in fname_list]
    ... do stuff with src_file and the values in files ...
... src_file and all elements in stack cleaned up on block exit ...

3
投票
重要的是,如果任何一个失败,那么在此之前成功的所有the都将按确定性地清理;在这种情况下,大多数天真的解决方案最终都无法清理,最多依靠垃圾收集器,并且在诸如无需收集的锁定的情况下,没有释放锁。

在此处被置于此问题,因为这个问题被标记为未指定Python版本的duplate的“原始”。


open

大约翻译为

open

在您的情况下,我不会使用

with open(...) as f: 
    # do stuff 
语法。如果您有文件名列表,请执行此类操作。
f = open(...)
# do stuff
f.close()

如果您真的想使用

with open语法,则可以制作自己的上下文管理器,以接受文件名列表

filenames = os.listdir(file_directory) open_files = map(open, filenames) # do stuff for f in open_files: f.close()

1
投票
with open

在这种情况下,我看到使用上下文管理器的唯一优势是您不能忘记关闭文件。但是手动关闭文件没有错。请记住,当您的程序退出时,操作系统将收回其资源。


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.