Método sin locking para analizar (transmitir) XML en python

Tengo un documento XML que llega a través de un socket que necesito analizar y reactjsr sobre la marcha (es decir, analizar un árbol parcial). Lo que me gustaría es un método de no locking para hacerlo, de modo que pueda hacer otras cosas mientras espero que entren más datos (sin subprocesos).

Algo como iterparse sería ideal si terminara de iterar cuando el búfer de lectura estaba vacío, por ejemplo:

context = iterparse(imaginary_socket_file_wrapper) while 1: for event, elem in context: process_elem(elem) # iteration of context finishes when socket has no more data do_other_stuff() time.sleep(0.1) 

Supongo que SAX también sería una opción, pero iterparse parece más simple para mis necesidades. ¿Algunas ideas?

Actualizar:

El uso de hilos está bien, pero introduce un nivel de complejidad que esperaba eludir. Pensé que las llamadas no bloqueadas serían una buena manera de hacerlo, pero me parece que aumenta la complejidad de analizar el XML.

Bucear en la fuente iterparse me proporcionó la solución. Este es un ejemplo simple de cómo construir un árbol XML sobre la marcha y procesar elementos después de sus tags de cierre:

 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) 

En mi caso, terminé enviándolo con datos retorcidos, pero también debería funcionar con un socket no bloqueante.

Creo que hay dos componentes para esto, la E / S de red sin locking y un analizador XML orientado a la transmisión.

Para el primero, tendría que elegir un marco de red sin locking, o rodar su propia solución para esto. Sin duda, Twisted funcionaría, pero personalmente me parece difícil invertir el control de los marcos de control. Es probable que deba realizar un seguimiento de muchos estados en sus devoluciones de llamada para alimentar el analizador. Por esta razón, tiendo a encontrar que Eventlet es un poco más fácil de progtwigr y creo que encajaría bien en esta situación.

Esencialmente, te permite escribir tu código como si estuvieras usando una llamada de socket de locking (usando un bucle ordinario o un generador o lo que quieras), excepto que puedes engendrarlo en una secuencia separada (una “greenlet”) que automáticamente realice un rendimiento cooperativo cuando las operaciones de E / S se bloquearían, permitiendo así que otras coroutinas se ejecuten.

Esto hace que el uso de cualquier analizador orientado a secuencias sea trivial de nuevo, porque el código está estructurado como una llamada de locking normal. También significa que muchas bibliotecas que no tratan directamente con sockets u otras E / S (como el analizador, por ejemplo) no tienen que ser modificadas especialmente para que no se bloqueen: si se bloquean, Eventlet produce la rutina.

Es cierto que Eventlet es ligeramente mágico, pero me parece que tiene una curva de aprendizaje mucho más fácil que Twisted, y da como resultado un código más directo porque no tiene que convertir su lógica “al revés” para ajustarse al marco.

Si no usa hilos, puede usar un bucle de eventos y sondear sockets no bloqueadores.

asyncore es el módulo de biblioteca estándar para tales cosas. Twisted es la biblioteca asíncrona para Python, pero compleja y probablemente un poco pesada para sus necesidades.

Alternativamente, el multiprocessing es la alternativa de subproceso sin subprocesos, pero supongo que no está ejecutando 2.6.

De una forma u otra, creo que tendremos que usar hilos, procesos adicionales o tejer una magia asíncrona igualmente compleja.