Python 2.7 逐字遍历大文件时出现 MemoryError
MemoryError in Python 2.7 when iterating over a large file word by word
我需要多次读取一个大文件并且需要访问文件中的总字数。我实现了一个包装器 class,其中包含一个迭代器、一个迭代器副本(用于重置迭代器)及其长度:
Class DataWrapper(object):
def __init__(self, data):
self.data, self.copy = itertools.tee(data)
self.length = None
def __iter__(self):
return self.data
def next(self):
return self.data.next()
def reset(self):
self.data, self.copy = itertools.tee(self.copy)
def __len__(self):
if self.length is None:
self.data, dcopy = itertools.tee(self.data)
self.length = sum(1 for x in dcopy)
return self.length
然后我创建实际的文件读取迭代器并开始迭代:
def my_iter(fname):
with open(fname, 'r') as f:
for line in f:
for word in line.split():
yield word
dw = DataWrapper(my_iter("large_file.txt"))
for w in dw:
pass
不过出于某种原因,我在迭代时得到了 MemoryError
:
文件 "my_script.py",第 164 行,在 my_iter 中
对于 f 中的行:
内存错误
由于没有包装器就不会发生这种情况,我认为 itertools.tee
是罪魁祸首。但是有没有另一种方法来重置迭代器?
这里的问题是,如果数据只读一次,要迭代多次,就得一直保存在内存中。如果文件大到足以耗尽内存,您将以 MemoryError 结束。这里的 itertool.tee
确实是罪魁祸首,即使恕我直言,这也不是罪魁祸首,因为它没有其他办法;-)
如果您不能将数据保存在内存中,唯一万无一失的方法是为每个迭代器打开一个新的文件处理程序 - 前提是 OS 和文件系统允许这样做。这样内存将只包含一个缓冲区和每个迭代器一行而不是整个文件。
我需要多次读取一个大文件并且需要访问文件中的总字数。我实现了一个包装器 class,其中包含一个迭代器、一个迭代器副本(用于重置迭代器)及其长度:
Class DataWrapper(object):
def __init__(self, data):
self.data, self.copy = itertools.tee(data)
self.length = None
def __iter__(self):
return self.data
def next(self):
return self.data.next()
def reset(self):
self.data, self.copy = itertools.tee(self.copy)
def __len__(self):
if self.length is None:
self.data, dcopy = itertools.tee(self.data)
self.length = sum(1 for x in dcopy)
return self.length
然后我创建实际的文件读取迭代器并开始迭代:
def my_iter(fname):
with open(fname, 'r') as f:
for line in f:
for word in line.split():
yield word
dw = DataWrapper(my_iter("large_file.txt"))
for w in dw:
pass
不过出于某种原因,我在迭代时得到了 MemoryError
:
文件 "my_script.py",第 164 行,在 my_iter 中 对于 f 中的行: 内存错误
由于没有包装器就不会发生这种情况,我认为 itertools.tee
是罪魁祸首。但是有没有另一种方法来重置迭代器?
这里的问题是,如果数据只读一次,要迭代多次,就得一直保存在内存中。如果文件大到足以耗尽内存,您将以 MemoryError 结束。这里的 itertool.tee
确实是罪魁祸首,即使恕我直言,这也不是罪魁祸首,因为它没有其他办法;-)
如果您不能将数据保存在内存中,唯一万无一失的方法是为每个迭代器打开一个新的文件处理程序 - 前提是 OS 和文件系统允许这样做。这样内存将只包含一个缓冲区和每个迭代器一行而不是整个文件。