如何在Python3中非阻塞地获取用户输入?

0 投票
1 回答
904 浏览
提问于 2025-04-16 08:33

我正在尝试对从客户端发送到服务器的命令进行类型检查。我想使用选择(select)来避免阻塞任何操作,但如果我直接使用 input(),就会导致阻塞。因此,我觉得应该用 sys.stdin.readline() 来代替。不过,这样一来,输入的命令和我想要进行的类型检查之间就出现了脱节:

while not self.flag:
    sock_read, sock_write, sock_except = \
        select.select([sys.stdin, self.client], [], [])

    for sock in sock_read:
        if sock == sys.stdin:
            data = sys.stdin.readline().strip()
            if data:
                self.client.send(data.encode('utf_8'))
        elif sock == self.client:
            data = sock.recv(bufsize)
            if data.decode('utf_8') is '':  # server closed connection
                print("Lost connection to server, shutting down...")
                self.flag = True
                break
            else:   # process data '\n' delimited
                readbuf += data
                while b'\n' in readbuf:
                    msg,readbuf = readbuf.split(b'\n', 1) # separate by \n
                    msg = msg.decode('utf_8')
                    msg.strip('\n')
                    # make below into a function
                    # got data from server
                    if msg == 'BEGIN':
                        self.playstarted = True
                    elif msg == 'GO':
                        #command = input("Your turn: ")
                        # typecheck command, something like
                        # while is_not_valid_command():
                        #   keep asking for input
                        print("You",command)

                        command += '\n' # delimiter
                        sock.send(command.encode('utf_8'))
                    else:
                        sys.stdout.write(msg + "\n")
                        sys.stdout.flush()

简单来说,如果客户端不把接收到的数据识别为命令,它就会认为这只是聊天信息,并相应地将其写入标准输出(stdout)。但是,当我收到像 'GO' 这样的命令时,我需要客户端提示用户输入命令(或者只是显示一条消息来询问输入,这样我就不会因为 input() 而阻塞),以便我可以在同一个层级中对命令进行类型检查。这种情况可以在不使用线程的情况下实现吗?

1 个回答

1

我觉得在不使用线程的情况下,input() 函数是无法做到非阻塞的。

撰写回答