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(即打字机打印纸),所以发送纯文本就可以了,但是交互式编辑(即使在一行内)是好的一个黑客。也就是说,它应该主要工作
我正在构建一个命令行工具,用户可以在其中输入命令并使命令编辑更愉快,我使用 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(即打字机打印纸),所以发送纯文本就可以了,但是交互式编辑(即使在一行内)是好的一个黑客。也就是说,它应该主要工作