NLTK 以非阻塞方式绘制树

NLTK draw tree in non-blocking way

NLTK 提供了一项功能,允许您 "draw" 树结构,例如依赖解析。实际上,当您调用 tree.draw() 时,会弹出一个 windows(至少在 Windows 上)和绘制的树。尽管这是一个很好的功能,但它也会阻塞,这意味着在绘制树时脚本的执行将被阻塞,直到您关闭新绘制的树的 window。

有没有办法以非阻塞方式绘制树,即没有它们停止脚本的执行?我考虑过在 Python 中启动一个单独的进程来负责绘制树,但也许有更直接的方法。

NLTK 使用 Tkinter canvas 来显示树结构。 Tkinter 有一个 mainloop 方法,它可以等待事件并更新 GUI。但是这个方法会阻塞它后面的代码(更多关于这个here and here)。
我们可以使用非阻塞的 update 方法代替 mainloop 方法。它更新 Tkinter canvas 然后 returns.
以下是我们如何使用 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()