Python3如何实现带超时限制的单字符键盘输入读取?
Python3 无回车带超时单字符输入实现方案
原有实现的核心问题是将倒计时逻辑和输入监听逻辑串行执行,且使用的
inputimeout本质还是基于标准行缓冲输入,必须等待回车确认,因此触发了三个体验问题。
跨平台原生实现(无需第三方依赖)
兼容Windows、macOS、Linux系统,无需安装额外库:
import sys import time class _Getch: """跨平台读取单字符,无需回车""" def __init__(self): try: self.impl = _GetchWindows() except ImportError: self.impl = _GetchUnix() def __call__(self): return self.impl() class _GetchUnix: def __init__(self): import tty import termios def __call__(self): import sys import tty import termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch class _GetchWindows: def __init__(self): import msvcrt def __call__(self): import msvcrt return msvcrt.getch().decode('utf-8') getch = _Getch() def get_choice(maxtimeout=9): prompt = "是否继续处理下一条目(Y/N)? {:2d} 秒后默认选择Y..." for remaining in range(maxtimeout, 0, -1): # 刷新倒计时提示 sys.stdout.write(f"\r{prompt.format(remaining)}") sys.stdout.flush() # 每秒内轮询10次检查是否有输入,降低响应延迟 for _ in range(10): # 分系统检查输入状态 if sys.platform.startswith('win'): import msvcrt if msvcrt.kbhit(): c = getch().upper() if c in ('Y', 'N'): sys.stdout.write(f"\r{prompt.format(remaining)} 输入已确认: {c}\n") return c else: import select if select.select([sys.stdin], [], [], 0.1)[0]: c = getch().upper() if c in ('Y', 'N'): sys.stdout.write(f"\r{prompt.format(remaining)} 输入已确认: {c}\n") return c time.sleep(0.1) # 超时默认返回Y sys.stdout.write(f"\r{prompt.format(0)} 超时默认选择: Y\n") return 'Y'
实现效果说明
- 无需按下回车:关闭了终端默认行缓冲模式,按下按键后立刻读取输入内容
- 提前输入立刻响应:倒计时过程中每0.1秒轮询一次输入状态,捕获到合法的Y/N输入后立刻返回,无需等待超时结束
- 输入实时反馈:捕获到输入后立刻在终端打印确认内容,无需等待倒计时结束
如果希望简化代码量,也可以安装第三方库readchar替换原生的单字符读取逻辑,核心的倒计时+轮询输入逻辑和上述代码一致。
内容的提问来源于stack exchange,提问作者ishandutta2007
相关产品推荐
相关产品推荐

