如何在不阻塞整个应用程序的情况下读取单个击键?

How to read single keystrokes without blocking the whole application?

因为我没有找到更好的方法来读取命令行上的击键我目前正在使用 getch()

不幸的是,像这样使用 getch() 会停止 stdout 上的输出:

while True:
    handle_keystroke(getch())

按下按钮会触发 handle_keystroke() 并在终端中打印 stdout - 每次击键时逐行打印。

提供的建议 here 没有帮助。

我做错了什么?

顺便说一句:我 不需要 使用 getch()。有没有更好的方法(例如使用select())?

更新:(更改标题)

所有这些只有在您使用多个线程时才会成为问题。所以看起来 getch (这是一个非 Python 函数)没有释放 GIL,所以所有其他线程都被挂起,所以不仅 stdout 受到影响。

好的,找到了使用 select 而不是 getch() 的方法。诀窍是将 sys.stdout 的模式设置为 cbreak:

import select
import tty
import termios
from contextlib import contextmanager

@contextmanager
def cbreak(stream):
    """Set fd mode to cbreak"""
    old_settings = termios.tcgetattr(stream)
    tty.setcbreak(stream.fileno())
    yield
    termios.tcsetattr(stream, termios.TCSADRAIN, old_settings)

with cbreak(sys.stdin):
    while True:
        select.select([sys.stdin], [], []) == ([sys.stdin], [], [])
        key = sys.stdin.read(1)
        handle_keystroke(key)