gpt4 book ai didi

python - 如何使用 "with open"语句打开多个文件(事先未知的文件数)?

转载 作者:太空宇宙 更新时间:2023-11-04 09:05:04 26 4
gpt4 key购买 nike

我特别需要使用 with open 语句来打开文件,因为我需要同时打开几百个文件并使用 K-way merge 合并它们。我明白,理想情况下我应该保持低 K,但我没有预见到这个问题。

现在不能从头开始,因为我有截止日期。所以在这一点上,我需要非常快的 I/O,它不会将文件的整个/大部分存储在内存中(因为有数百个文件,每个大约 10MB)。对于 K-way 合并,我只需要一次阅读一行。减少内存使用量是我目前的主要关注点。

我了解到 with open 是最有效的技术,但我不明白如何在一个 with openopen 所有文件> 声明。原谅我的初学者无知!

更新:这个问题已经解决了。事实证明,问题根本不在于我如何打开文件。我发现内存使用过多是由于垃圾收集效率低下造成的。我根本没有使用 with open。我使用了常规的 f=open()f.close()。垃圾收集挽救了局面。

最佳答案

使用内置的 contextmanger 编写自己的上下文管理器来处理这个问题相当容易。函数装饰器来定义“with 语句上下文管理器的工厂函数”,正如文档所说的那样。例如:

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用作基类以简化 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')

关于python - 如何使用 "with open"语句打开多个文件(事先未知的文件数)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21680473/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com