【发布时间】: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