python readline 和异步打印

python readline and asynchronous printing

我正在构建一个命令行工具,用户可以在其中输入命令并使命令编辑更愉快,我使用 readline。其他线程中也可能发生重要事件,这些事件必须打印到控制台。然而,简单地用 print() 打印它们会弄乱 readline 提示。有没有办法在不弄乱 readline 的情况下打印一行?这是一个例子:

import readline
from threading import Timer

def event():
    print('Async event happened!')

t = Timer(3, event)
t.start()

a = input('CLI> ')
print('You entered:', a)

如果我输入 start 但还没有按回车键,然后等待事件发生,那么控制台将如下所示(_ 是光标):

CLI> startAsync event happened!
_

但我希望它看起来像下面这样:

Async event happened!
CLI> start_

必须使用锁才能有序打印。

import threading

print_lock = threading.Lock()

def thread1():
...
    with print_lock:
        print('blabla')

def thread2():
...
    with print_lock:
        print('bla')

很确定你不能用通过标准库公开的 readline 接口来做到这一点,如果你在使用其他库方面有一定的灵活性,你可以尝试 prompt toolkit 包上下文管理器可以很好地修补事物,因此它们可以按您希望的方式工作:

from prompt_toolkit import prompt
from prompt_toolkit.patch_stdout import patch_stdout
import threading

def fn():
    print('async event')

with patch_stdout():
    threading.Timer(3, fn).start()
    a = prompt('Cli> ')

print('got', repr(a))

对我有用

请注意,这类事情会破坏 unix TTY 处理的各个方面,因此总是会 delicate/easy 破坏。事物背后的抽象仍然基于 "console" 是 "teletype" device(即打字机打印纸),所以发送纯文本就可以了,但是交互式编辑(即使在一行内)是好的一个黑客。也就是说,它应该主要工作