【问题标题】:Python – select on unbuffered stdinPython – 在无缓冲的标准输入上选择
【发布时间】:2020-08-04 14:59:52
【问题描述】:

我真的在 python3 中为缓冲而苦苦挣扎。我正在尝试实现一个简单的收音机。

我有一个接收器类。它向用户显示可用的电台。这些电台是动态的,因此它们会出现和消失。

Welcome to the radio, select station you want to listen to.
> 1) Rock Station
  2) Hip Hop Station
  3) Country Station

因此接收器必须同时等待输入:来自管道(有关新站点出现/消失的信息)和来自 Stdin(用户可以使用向上和向下箭头来更改站点)。

此外,当用户使用箭头键更改电台时,我必须一次从标准输入读取一个字符。

这就是标准 select.select 不起作用的原因(它等待用户按下 ENTER 键):


class _GetchUnix:
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, 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


self.char_reader = _GetchUnix()
[...]

def __read_order_from_user(self,):
    k = self.char_reader()
    # Check for up/down arrow keys.
    if k == '\x1b':
        k = self.char_reader()
        if k != '[':
            return
        k = self.char_reader()
        if k == 'A':
            self.__arrow_down()
        if k == 'B':
            self.__arrow_up()

    # And check for enter key.
    if k == '\r':
        self.menu[self.option].handler()


def __update_stations(self,):
    [...]

def run(self):
    self.display()
    while True:
        rfds, _, _ = select.select([pipe, sys.stdin], [], [])

        if pipe in rfds:
                self.__update_stations()

        if sys.stdin in rfds:
            self.__read_order_from_user()

我在互联网上找到了如何从标准输入中逐个读取字符:Python read a single character from the user 它确实有效,但与select.select 一起使用时无效。

【问题讨论】:

  • raw tty 模式打开为只读取一个字符,然后关闭。当 select 处于活动状态时,它被关闭,因为在 select 之后调用了获取一个字符的例程。您应该在选择循环之前打开原始 tty 输入,并在退出循环后恢复 tty 设置。希望这条短信对您有所帮助,我现在要离开电脑了。
  • 嗯,是的,它有帮助:) 谢谢:)

标签: python pipe buffer stdin buffering


【解决方案1】:

我在此处粘贴来自 VPfB 评论的解决方案:

"The raw tty mode is turned on to only to read one character and then turned off. When the select is active, it is turned off, because the routine to get the one character is called after the select. You should turn在选择循环之前输入原始 tty 并在退出循环后恢复 tty 设置。"

【讨论】:

    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2012-05-02
    • 2014-12-07
    • 1970-01-01
    • 2011-05-18
    相关资源
    最近更新 更多