У меня есть большой файл данных XML (> 160 МБ) для обработки, и похоже, что разбор SAX / expat / pulldom - это путь. Я хотел бы иметь поток, который просеивает через узлы и помещает узлы для обработки в очередь, а затем другие рабочие потоки вытягивают следующий доступный узел из очереди и обрабатывают его.
У меня есть следующее (оно должно иметь блокировки, я знаю, что оно будет позже)
import sys, time
import xml.parsers.expat
import threading
q = []
def start_handler(name, attrs):
q.append(name)
def do_expat():
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_handler
p.buffer_text = True
print("opening {0}".format(sys.argv[1]))
with open(sys.argv[1]) as f:
print("file is open")
p.ParseFile(f)
print("parsing complete")
t = threading.Thread(group=None, target=do_expat)
t.start()
while True:
print(q)
time.sleep(1)
Проблема в том, что тело блока while
вызывается только один раз, и тогда я не могу даже ctrl-C прервать его. В меньших файлах вывод такой же, как и ожидалось, но, похоже, это указывает на то, что обработчик вызывается только тогда, когда документ полностью проанализирован, что, по-видимому, противоречит цели парсера SAX.
Я уверен, что это мое собственное невежество, но я не понимаю, где я совершаю ошибку.
PS: я также пытался изменить start_handler
таким образом:
def start_handler(name, attrs):
def app():
q.append(name)
u = threading.Thread(group=None, target=app)
u.start()
Хотя любви нет.