Python开发web服务器时如何将控制台当前输入行下移并保留已输入内容
解决方案
要实现该效果核心是需要主动跟踪当前未提交的输入内容,在输出新日志前先清空当前输入行、输出日志,再把输入行完整还原到新的一行,具体实现如下:
完整可运行代码
import threading import time import sys import readline # Windows下开启ANSI转义码支持 if sys.platform == "win32": import ctypes kernel32 = ctypes.windll.kernel32 kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) def safe_log(msg: str): # 保存当前输入状态 input_buffer = readline.get_line_buffer() cursor_pos = readline.get_endidx() # 清空当前输入行 sys.stdout.write("\r\033[2K") # 输出日志 sys.stdout.write(f"{msg}\n") # 还原输入行 sys.stdout.write(f"> {input_buffer}") # 移动光标到原来的位置,+2是因为提示符"> "占2个字符 sys.stdout.write(f"\033[{cursor_pos + 2}G") sys.stdout.flush() # 模拟后台收到请求打印日志 def mock_request(): for i in range(5): time.sleep(2) safe_log(f"Request from 127.0.0.1 - GET /test{i}.html") if __name__ == "__main__": t = threading.Thread(target=mock_request, daemon=True) t.start() safe_log("Request from 127.0.0.1 - GET /index.html") while True: cmd = input("> ") if cmd.strip() == "exit": break safe_log(f"执行命令: {cmd}")
关键逻辑说明
- 使用Python标准库
readline获取用户当前已输入但未提交的内容、光标位置,不需要额外安装依赖 - 输出日志时用到的ANSI转义码作用:
\r:将光标移动到当前行最左侧\033[2K:清空当前光标所在的整行内容\033[{N}G:将光标移动到当前行的第N个字符位置
- 所有控制台输出都走
safe_log方法即可保证日志不会和输入内容混杂,已输入未提交的内容会自动跟随输入行下移,不会丢失。
如果需要更复杂的控制台交互能力(比如命令历史、自动补全),可以直接使用第三方库prompt_toolkit,它内置了异步输出不打断输入的功能,只需要调用内置的输出方法打印日志即可自动实现该效果,不需要手动处理转义码。
内容的提问来源于stack exchange,提问作者Fun840
相关产品推荐
相关产品推荐

