You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现控制台聊天系统:如何向stdout前置添加数据且不覆盖内容?

控制台聊天系统的实时消息与输入同步解决方案

一、修复示例代码的输出问题

你的示例代码使用\r(回车符)会将光标移至行首,导致后续内容直接覆盖之前的输出。要实现hello there的期望输出,只需移除\r,调整输出逻辑即可:

import sys

my_words = ['there', 'hello']
# 逆序遍历输出,拼接成目标字符串
output = ' '.join(reversed(my_words)) + '\n'
sys.stdout.write(output)
sys.stdout.flush()

二、控制台聊天系统核心实现方案

要同时处理用户输入(input())和实时消息接收,需用多线程分离输入与消息监听逻辑,同时通过ANSI转义序列控制光标和行内容,避免输入提示被打断偏移。

实现逻辑

  • 主线程:负责用户输入,保持输入提示正常显示。
  • 子线程:监听并接收消息,收到消息时先清空当前输入行,打印消息后重新恢复输入提示(含用户已输入的内容)。

完整代码示例

import sys
import threading
import time

# 模拟消息接收(实际场景替换为网络消息监听逻辑)
def receive_messages(input_prompt):
    msg_id = 0
    while True:
        time.sleep(2)  # 模拟消息间隔
        new_msg = f'Received: chat_msg_{msg_id}'
        msg_id += 1

        # 清除当前输入行并打印新消息
        sys.stdout.write('\x1b[2K\r')  # \x1b[2K清除整行,\r移光标到行首
        print(new_msg)
        # 重新输出输入提示,保证输入流程不中断
        sys.stdout.write(input_prompt)
        sys.stdout.flush()

def main():
    prompt = 'Enter your message: '
    # 启动消息接收守护线程,主线程退出时自动终止
    threading.Thread(target=receive_messages, args=(prompt,), daemon=True).start()

    while True:
        user_input = input(prompt)
        print(f'You sent: {user_input}')

if __name__ == '__main__':
    main()

关键细节

  • \x1b[2K:ANSI转义序列,用于清除当前整行内容,避免消息打印时和输入提示混叠。
  • 若需保留用户已输入的半完成内容,可以添加线程安全的变量存储输入进度,在恢复提示时拼接进去,进一步优化体验。

内容的提问来源于stack exchange,提问作者Gernit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:55:57