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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:39:55