由於iterparse
遍歷整個文件構建樹並且沒有元素被釋放。這樣做的好處是元素會記住他們的父母是誰,並且可以形成引用祖先元素的XPath。缺點是它會消耗大量的內存。
爲了釋放一些內存爲你解析,使用麗莎達利的fast_iter
:
def fast_iter(context, func, *args, **kwargs):
"""
http://lxml.de/parsing.html#modifying-the-tree
Based on Liza Daly's fast_iter
http://www.ibm.com/developerworks/xml/library/x-hiperfparse/
See also http://effbot.org/zone/element-iterparse.htm
"""
for event, elem in context:
func(elem, *args, **kwargs)
# It's safe to call clear() here because no descendants will be
# accessed
elem.clear()
# Also eliminate now-empty references from the root node to elem
for ancestor in elem.xpath('ancestor-or-self::*'):
while ancestor.getprevious() is not None:
del ancestor.getparent()[0]
del context
然後你可以使用這樣的:
def process_element(elem):
print "why does this consume all my memory?"
context = lxml.etree.iterparse('really-big-file.xml', tag='schedule', events = ('end',))
fast_iter(context, process_element)
我強烈建議the article在其上面fast_iter
基於;如果您正在處理大型XML文件,那麼您應該特別感興趣。
上面介紹的fast_iter
是文章中顯示的 的一個稍作修改的版本。這個刪除以前的祖先更積極, 從而節省更多的內存。 Here you'll find a script它演示了 的區別。
謝謝!您的解決方案和我剛剛添加的解決方案似乎都有訣竅,我很好奇您和其他人都認爲哪種解決方案更好。你有什麼想法嗎? –
原來你的解決方案有效並且http://effbot.org/zone/element-iterparse.htm解決方案沒有(它仍然吃掉了我所有的記憶) –
謝謝!這是真正有效的版本。 Liza Daly,effbot和lxml官方文檔的版本並沒有爲我節省太多內存。 – fjsj