Python не хватает памяти для разбора XML с помощью cElementTree.iterparse - PullRequest
18 голосов
/ 08 октября 2011

Упрощенная версия моей функции синтаксического анализа XML здесь:

import xml.etree.cElementTree as ET

def analyze(xml):
    it = ET.iterparse(file(xml))
    count = 0

    for (ev, el) in it:
        count += 1

    print('count: {0}'.format(count))

Это заставляет Python исчерпать память, что не имеет большого смысла. Единственное, что я на самом деле храню, это число, целое число. Почему он это делает:

enter image description here

Видите это внезапное падение памяти и использования процессора в конце? Это Python эффектно падает. По крайней мере, он дает мне MemoryError (в зависимости от того, что еще я делаю в цикле, он дает мне больше случайных ошибок, таких как IndexError) и трассировку стека вместо segfault. Но почему он падает?

Ответы [ 2 ]

12 голосов
/ 09 октября 2011

Документация говорит вам "Разбирает секцию XML в дерево элементов [мой акцент] постепенно", но не описывает, как избежать сохранения неинтересных элементов (которые могут быть все они). Это покрыто этой статьей effbot .

Я настоятельно рекомендую всем, кто использует .iterparse(), прочитать эту статью Лизы Дейли . Он охватывает как lxml, так и [c] ElementTree.

Предыдущее покрытие по SO:

Использование Python Iterparse для больших файлов XML
Может ли Python xml ElementTree анализировать очень большой XML-файл?
Какой самый быстрый способ анализа больших XML-документов в Python?

5 голосов
/ 07 ноября 2012

Пример кода:

import xml.etree.cElementTree as etree

def getelements(filename_or_file, tag):
    context = iter(etree.iterparse(filename_or_file, events=('start', 'end')))
    _, root = next(context) # get root element
    for event, elem in context:
        if event == 'end' and elem.tag == tag:
            yield elem
            root.clear() # preserve memory
...