【问题标题】:Python: How to print without overwriting current typed input?Python:如何在不覆盖当前输入的情况下打印?
【发布时间】:2018-12-20 03:45:53
【问题描述】:

是否可以在不覆盖已写入但未发送的输入的情况下打印某些内容?

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

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()

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

【问题讨论】:

    标签: python


    【解决方案1】:

    s.sendall(bytes(text, 'utf-8')) 之后添加time.sleep(10),因为您在稍后接收和打印数据时立即进行输入。有了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
    

    【讨论】:

      【解决方案2】:

      交互式终端输入很复杂,通常由库处理,很难直接处理。对于行输入,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 模块导出的。

      【讨论】:

      • (不确定我的方法是否是正确的方法,并且它在终端和readline的版本之间100%可移植)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 1970-01-01
      • 2017-11-13
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多