Python:readline / input()与来自不同线程的输出进行交互

时间:2018-09-24 07:52:54

标签: python multithreading readline

我正在使用交互式控制台编写多线程程序:

def console()
    import readline
    while True:
        data = input()
        do_whatever(data.split())

但是,我正在使用的库从其他线程运行回调。回调需要打印到控制台。因此,我想清除命令行,重新显示提示,然后重新显示命令行。

在不重新实现readline的情况下,我该怎么做?

1 个答案:

答案 0 :(得分:0)

从解决C问题的this answer开始,我得出了以下Python代码,这些代码足以满足我的目的:

import os
import readline
import signal
import sys
import time
import threading


print_lock = threading.Lock()

def print_safely(text):
    with print_lock:
        sys.stdout.write(f'\r\x1b[K{text}\n')
        os.kill(os.getpid(), signal.SIGWINCH)

def background_thread():
    while True:
        time.sleep(0.5)
        print_safely('x')

threading.Thread(target=background_thread, daemon=True).start()

while True:
    try:
        inp = input(f'> ')
        with print_lock:
            print(repr(inp))
    except (KeyboardInterrupt, EOFError):
        print('')
        break

print_safely

  • 使用\r\x1b[K CR + CSI code EL )删除现有的Readline提示
  • 打印其有效载荷行
  • SIGWINCH 发送到运行readline的线程(在我的情况下,readline在主线程中运行,因此os.getpid()提供正确的目标PID);这会导致readline重新绘制其完整提示。

可能的剩余问题:

  • 如另一个答案中所述,如果readline提示符长于一行,则行清除很可能会失败。
  • 每当在主线程中打印时,您都需要获取print_lock(与readline问题无关,这是真的)
  • 当用户在打印后台线程的同一时间按下某个键时,可能会出现一些不道德的行为。