Python:如何在不覆盖当前类型输入的情况下进行打印?

时间:2018-12-19 18:39:10

标签: python

是否可以打印某些内容而不会覆盖已写入但尚未发送的输入?

这是套接字的客户端,我想从服务器打印消息而不会覆盖/附加当前写入的输入。

def listen():
    while True:
        data = s.recv(1024)
        print(data.decode('utf-8'))

def write():
    while True:
        text = input("Text > ")
        s.sendall(bytes(text, 'utf-8'))

listener = threading.Thread(target=listen)
listener.start()

writer = threading.Thread(target=write)
writer.start()

我想在当前输入行的上方或下方打印接收到的数据,但是现在它只是将其写在输入行上。

2 个答案:

答案 0 :(得分:0)

time.sleep(10)之后添加s.sendall(bytes(text, 'utf-8')),因为在接收数据并稍后打印时会立即进行输入。让time.sleep使您有时间接收和打印数据。

但是如果您输入input的数据太慢,这将无济于事。通常,代码很奇怪,因为为什么要在同一终端上执行inputprint?在现实生活中,这没有任何意义。

出于学术目的,您可以尝试以下操作:

is_input_active = False

def listen():
    while True:
        data = s.recv(1024)
        while is_input_active:
            time.sleep(0.2)
        print(data.decode('utf-8'))

def write():
    global is_input_active
    while True:
        is_input_active = True
        text = input("Text > ")
        is_input_active = False
        s.sendall(bytes(text, 'utf-8'))

在此版本中,listen()将被阻止,直到input函数完成为止。如果您不想这样做,请尝试以下操作:

def listen():
    data = b''
    while True:
        data += s.recv(1024)  # accumulate
        while not is_input_active:
            print(data.decode('utf-8'))
            data = b''  # reset

答案 1 :(得分:0)

交互式终端输入很复杂,通常使用库处理,很难直接处理。对于行输入,readline及其替代品(例如libedit)很受欢迎。大多数shell和REPL使用此类库。

Python的标准库具有readline模块,该模块是readlinelibedit的接口。导入它会使input使用realine / libedit,因此它可以获得光标导航,甚至具有自动完成和历史记录功能。并且它允许您在终端中绘制某些内容后重新绘制输入行。

要在前一行中打印,可以使用ANSI转义码。

import threading
import sys
from time import sleep
import readline # importing readline makes input() use it

def listen():
    i = 0
    while True:
        i += 1
        sleep(1)
        # <esc>[s - save cursor position
        # <esc>[1A - move cursor up
        # \r - carriage return
        # print message
        # <esc>[u - restore cursor position
        sys.stdout.write("\x1b[s\x1b[1A\rOutput: "+str(i)+"\x1b[u")
        readline.redisplay()

def write():
    while True:
        print "" # make space for printing messages
        text = input("Text > ")

listener = threading.Thread(target=listen)
listener.daemon = True
listener.start()

write()

readline库还具有rl_message和其他有用的功能,但是它不是由python的readline模块导出的。