Python中如何通过ESC键终止input()输入并退出循环
解决Python input()中按ESC键取消输入的问题
问题根源:input()是阻塞式函数,会暂停程序执行直到用户输入完成并按下回车。你之前写的keyboard.is_pressed('esc')只会在input()执行前/后被检测,根本没机会在用户输入过程中响应ESC键。
下面提供几种可行的解决方案:
方案1:原生库实现(分系统)
Windows平台(用msvcrt)
无需额外安装库,直接利用系统自带的msvcrt读取单个按键:
import msvcrt import sys while True: print("\n请输入内容(按ESC返回):") input_buffer = [] while True: # 检测是否有按键按下 if msvcrt.kbhit(): key_byte = msvcrt.getch() # ESC键的ASCII码为27(十六进制\x1b) if key_byte == b'\x1b': print("\n已取消输入,返回上一级菜单") break # 回车键(Windows下是\r) elif key_byte == b'\r': print(f"\n你输入的内容:{''.join(input_buffer)}") break # 退格键(处理输入删除) elif key_byte == b'\x08': if input_buffer: input_buffer.pop() # 在控制台回退删除字符 sys.stdout.write('\b \b') sys.stdout.flush() # 普通可打印字符 else: try: char = key_byte.decode('gbk') # Windows默认编码 input_buffer.append(char) sys.stdout.write(char) sys.stdout.flush() except UnicodeDecodeError: # 忽略不可打印的特殊字符 pass # 外层循环:检测是否触发ESC退出 if key_byte == b'\x1b': break
Linux/macOS平台(用termios)
利用termios修改终端属性,实现无阻塞读取单个按键:
import sys import termios import tty def read_single_key(): """读取单个按键,不等待回车""" fd = sys.stdin.fileno() old_term_attr = termios.tcgetattr(fd) try: # 设置终端为原始模式,直接读取按键 tty.setraw(fd) key = sys.stdin.read(1) finally: # 恢复终端原有属性 termios.tcsetattr(fd, termios.TCSADRAIN, old_term_attr) return key while True: print("\n请输入内容(按ESC返回):") input_buffer = [] while True: key = read_single_key() # ESC键的ASCII码为27 if ord(key) == 27: print("\n已取消输入,返回上一级菜单") break # 回车键(Linux/macOS下是\n) elif key == '\n': print(f"\n你输入的内容:{''.join(input_buffer)}") break # 退格键(ASCII码127) elif ord(key) == 127: if input_buffer: input_buffer.pop() sys.stdout.write('\b \b') sys.stdout.flush() # 普通可打印字符 else: input_buffer.append(key) sys.stdout.write(key) sys.stdout.flush() # 外层循环:检测是否触发ESC退出 if ord(key) == 27: break
方案2:用keyboard库(跨平台)
如果坚持用keyboard库,需要用线程监听ESC键,避免被input()阻塞:
import keyboard import threading input_canceled = False def listen_for_esc(): global input_canceled # 等待ESC键按下 keyboard.wait('esc') input_canceled = True # 模拟回车键,让input()结束阻塞 keyboard.press_and_release('enter') while True: input_canceled = False # 启动后台线程监听ESC esc_thread = threading.Thread(target=listen_for_esc, daemon=True) esc_thread.start() print("\n请输入内容(按ESC返回):") user_input = input().strip() if input_canceled: print("已取消输入,返回上一级菜单") break else: print(f"你输入的内容:{user_input}") # 可添加其他业务逻辑
注意:
keyboard库需要先安装:pip install keyboard,Linux/macOS下可能需要sudo权限运行。
内容的提问来源于stack exchange,提问作者Yousef
相关产品推荐
相关产品推荐

