Я действительно борюсь с буферизацией в python3. Я пытаюсь реализовать простое радио.
У меня есть класс приемника. Он отображает доступные станции для пользователя. Эти станции являются динамическими c, поэтому они появляются и исчезают.
Welcome to the radio, select station you want to listen to.
> 1) Rock Station
2) Hip Hop Station
3) Country Station
Таким образом, получатель должен ждать ввода как из канала (информация о появлении / исчезновении новой станции), так и из Stdin. (пользователь может использовать стрелки вверх и вниз для смены станции).
Более того, поскольку пользователь меняет станции с помощью клавиш со стрелками, я должен читать по одному символу за раз из стандартного ввода.
Это почему стандарт select.select
не работает (он ждет, когда пользователь нажмет клавишу ВВОД):
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()
Я нашел в inte rnet, как читать один за другим символ из stdin: Python читает один символ от пользователя , и он работает, но не при использовании вместе с select.select
.