我有35.5Mb .XLSM文件.当实际可用内容被扩展时,它会在漫长的运行时间之后淹没DOM解析器,例如元素树耗尽内存.
但是,在使用SAX解析器时,ContentHandler似乎限制在临时文件中累积行.这有点令人恼火,因为解析器和主应用程序可能有一个简单的协同例程关系,其中SAX解析的每一行都可以产生给应用程序.
它看起来不像以下是可能的.
def gen_rows_from_xlsx( someFile ):
myHandler= HandlerForXLSX()
p= xml.sax.makeParser()
p.setContentHandler( myHandler, some_kind_of_buffer )
for row in some_kind_of_buffer.rows():
p.parse() # Just enough to get to the ContentHandler's "buffer.put()"
yield row
Run Code Online (Sandbox Code Playgroud)
会定期HandlerForXLSX调用some_kind_of_buffer.put( row )将一行放入缓冲区.这一行应该通过some_kind_of_buffer.rows().
SAX解析器之间的简单协程关系gen_rows_from_xslx()将是理想的.
我是否忽略了一些生成器功能魔法,它允许我将SAX打包成某种协程?
是创建SAX解析线程并使用a Queue来获取解析器构建的行的唯一替代方法吗?
或者更容易咬住子弹并在SAX解析器中创建一个临时文件,然后通过生成器生成这些对象?
""我有35.5Mb .XLSM文件.当实际可用内容被扩展时,它会在很长很长的运行时间之后淹没像元素树耗尽内存的DOM解析器.""
我不明白这一点.你应该使用的东西:
import xml.etree.cElementTree as ET
ET.iterparse(sourcefile) # sourcefile being a cStringIO.StringIO instance holding your worksheet XML document
element.clear() # leave only scorched earth behind you
Run Code Online (Sandbox Code Playgroud)
本文介绍如何使用iterparse和clear.
示例:将XLSX(100Mb,其中大部分是两个工作表,每个包含大约16K行和大约200个col)加载到xlrd对象模型中:
经过时间约4分钟[打败旧笔记本电脑[2 GHz单核]运行Windows XP和Python 2.7].增量内存使用量最大约为300Mb内存,其中大部分是输出,而不是元素树.