- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我特别需要使用 with open
语句来打开文件,因为我需要同时打开几百个文件并使用 K-way merge 合并它们。我明白,理想情况下我应该保持低 K,但我没有预见到这个问题。
现在不能从头开始,因为我有截止日期。所以在这一点上,我需要非常快的 I/O,它不会将文件的整个/大部分存储在内存中(因为有数百个文件,每个大约 10MB)。对于 K-way 合并,我只需要一次阅读一行。减少内存使用量是我目前的主要关注点。
我了解到 with open
是最有效的技术,但我不明白如何在一个 with open
中open
所有文件> 声明。原谅我的初学者无知!
更新:这个问题已经解决了。事实证明,问题根本不在于我如何打开文件。我发现内存使用过多是由于垃圾收集效率低下造成的。我根本没有使用 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/
我想开发一个 Skype 机器人,它将用户名作为输入,并根据用户输入以相反的字符大小写表示hello username。简而言之,如果用户输入他的名字 james,我的机器人会回复他为 Hello J
我是一名优秀的程序员,十分优秀!