НЛТК рисует дерево неблокирующим способом - PullRequest
4 голосов
/ 22 января 2020

NLTK предоставляет функцию, которая позволяет «рисовать» древовидные структуры, например, анализ зависимостей. На практике, когда вы вызываете tree.draw(), всплывает windows (по крайней мере Windows) с нарисованным деревом. Несмотря на то, что это хорошая функциональность, она также блокирует, что означает, что выполнение сценария блокируется, когда дерево рисуется, пока вы не закроете окно вновь нарисованного дерева.

Есть ли способ нарисовать деревья в неблокирующим способом, то есть без их остановки выполнения скрипта? Я думал о запуске отдельного процесса в Python, который отвечает за рисование деревьев, но, возможно, есть более простой способ.

1 Ответ

4 голосов
/ 26 января 2020

NLTK использует холст Tkinter для отображения древовидных структур. Tkinter имеет метод mainl oop, который заставляет его ждать события и обновлять GUI. Но этот метод блокирует код после него (подробнее об этом здесь и здесь ).
Вместо метода mainl oop, который мы можем использовать update метод, который не является блокирующим. Он обновляет холст Tkinter и затем возвращает.
Вот как мы можем сделать это с NLTK:

import nltk
from nltk import pos_tag
pattern = """NP: {<DT>?<JJ>*<NN>}
... VBD: {<VBD>}
... IN: {<IN>}"""
NPChunker = nltk.RegexpParser(pattern)

sentences = ['the small dog is running',
             'the big cat is sleeping',
             'the green turtle is swimming'
            ]

def makeTree(sentence):
    tree = NPChunker.parse(pos_tag(sentence.split()))
    return(tree)

from nltk.draw.util import Canvas
from nltk.draw import TreeWidget
from nltk.draw.util import CanvasFrame

cf = CanvasFrame()

for sentence in sentences:
    tree = makeTree(sentence)
    tc = TreeWidget(cf.canvas(), tree)
    cf.add_widget(tc)
    cf.canvas().update()


## .. the rest of your code here
print('this code is non-blocking')

#at the end call this so that the programm doesn't terminate and close the window
cf.mainloop()
...