Неблокирование метода для парсинга (потоковой передачи) XML в Python

В C/C++ перечисление будет тем же размером как интервал

С gcc, который можно добавить атрибут ((упакованный)) к перечислимому определению, чтобы заставить его взять минимальное место. Если самое большое значение в перечислении является < 256 это будет один байт, два байта, если самое большое значение будет < 65536, и т.д.

typedef enum {
    MY_ENUM0,
    MY_ENUM1,
    MY_ENUM2,
    MY_ENUM3,
    MY_ENUM4,
    MY_ENUM5
} __attribute__((packed)) myEnum_e;
7
задан Peter Gibson 23 September 2009 в 23:37
поделиться

3 ответа

Погружение в источник iterparse дало мне решение. Вот простой пример построения дерева XML на лету и обработки элементов после их закрывающих тегов:

import xml.etree.ElementTree as etree

parser = etree.XMLTreeBuilder()

def end_tag_event(tag):
    node = self.parser._end(tag)
    print node

parser._parser.EndElementHandler = end_tag_event

def data_received(data):
    parser.feed(data)

В моем случае я передавал ему данные из twisted, но он должен работать и с неблокирующим сокетом.

8
ответ дан 6 December 2019 в 19:39
поделиться

I think there are two components to this, the non-blocking network I/O, and a stream-oriented XML parser.

For the former, you'd have to pick a non-blocking network framework, or roll your own solution for this. Twisted certainly would work, but I personally find inversion of control frameworks difficult to wrap my brain around. You would likely have to keep track of a lot of state in your callbacks to feed the parser. For this reason I tend to find Eventlet a bit easier to program to, and I think it would fit well in this situation.

Essentially it allows you to write your code as if you were using a blocking socket call (using an ordinary loop or a generator or whatever you like), except that you can spawn it into a separate coroutine (a "greenlet") that will automatically perform a cooperative yield when I/O operations would block, thus allowing other coroutines to run.

This makes using any stream-oriented parser trivial again, because the code is structured like an ordinary blocking call. It also means that many libraries that don't directly deal with sockets or other I/O (like the parser for instance) don't have to be specially modified to be non-blocking: if they block, Eventlet yields the coroutine.

Admittedly Eventlet is slightly magic, but I find it has a much easier learning curve than Twisted, and results in more straightforward code because you don't have to turn your logic "inside out" to fit the framework.

4
ответ дан 6 December 2019 в 19:39
поделиться

Если вы не используете потоки, вы можете использовать цикл обработки событий и опросить неблокирующие сокеты.

asyncore - стандартный библиотечный модуль для таких вещей. Twisted - это асинхронная библиотека для Python, но сложная и, вероятно, несколько тяжеловесная для ваших нужд.

В качестве альтернативы многопроцессорность является альтернативой непотоковым потокам , но я предполагаю, что вы не используете 2.6.

Так или иначе, я думаю, вам придется использовать потоки, дополнительные процессы или создать не менее сложную асинхронную магию.

1
ответ дан 6 December 2019 в 19:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: