Как очистить поток ввода в Python? - PullRequest
12 голосов
/ 26 марта 2010

Я пишу простую утилиту тревоги на Python.

#!/usr/bin/python

import time
import subprocess
import sys

alarm1 = int(raw_input("How many minutes (alarm1)? "))

while (1):
    time.sleep(60*alarm1)
    print "Alarm1"
    sys.stdout.flush()
    doit = raw_input("Continue (Y/N)?[Y]: ")
    print "Input",doit
    if doit == 'N' or doit=='n':
        print "Exiting....."
        break

Я хочу сбросить или отменить все нажатия клавиш, которые были введены во время сна сценария, и принимать нажатия клавиш только после выполнения raw_input ().

РЕДАКТИРОВАТЬ: я запускаю это на Windows XP.

Ответы [ 4 ]

10 голосов
/ 26 марта 2010

Было бы полезно узнать, какую операционную систему вы используете, поскольку это очень специфический вопрос для операционной системы. Например, ответ Кайлара не работает в Windows, поскольку sys.stdin не имеет атрибута fileno.

Мне было любопытно, и я собрал решение, используя проклятия, но это не будет работать и в Windows:

#!/usr/bin/python                                                               

import time
import sys
import curses

def alarmloop(stdscr):
    stdscr.addstr("How many seconds (alarm1)? ")
    curses.echo()
    alarm1 = int(stdscr.getstr())
    while (1):
        time.sleep(alarm1)
        curses.flushinp()
        stdscr.clear()
        stdscr.addstr("Alarm1\n")
        stdscr.addstr("Continue (Y/N)?[Y]:")
        doit = stdscr.getch()
        stdscr.addstr("\n")
        stdscr.addstr("Input "+chr(doit)+"\n")
        stdscr.refresh()
        if doit == ord('N') or doit == ord('n'):
            stdscr.addstr("Exiting.....\n")
            break

curses.wrapper(alarmloop)

РЕДАКТИРОВАТЬ: ах, Windows. Тогда вы можете использовать модуль msvcrt. Обратите внимание, что приведенный ниже код не идеален и вообще не работает в IDLE:

#!/usr/bin/python

import time
import subprocess
import sys
import msvcrt

alarm1 = int(raw_input("How many seconds (alarm1)? "))

while (1):
    time.sleep(alarm1)
    print "Alarm1"
    sys.stdout.flush()

    # Try to flush the buffer
    while msvcrt.kbhit():
        msvcrt.getch()

    print "Continue (Y/N)?[Y]"
    doit = msvcrt.getch()
    print "Input",doit
    if doit == 'N' or doit=='n':
        print "Exiting....."
        break
6 голосов
/ 17 августа 2016

С Розеттский код

def flush_input():
    try:
        import msvcrt
        while msvcrt.kbhit():
            msvcrt.getch()
    except ImportError:
        import sys, termios    #for linux/unix
        termios.tcflush(sys.stdin, termios.TCIOFLUSH)

Попробовать часть для платформы Windows. Я лично не проверял эту часть. Но секция кроме работает на терминале Linux. Модуль termios имеет некоторые функции интерфейса терминала. tcflush может сбрасывать входные или выходные буферизованные данные. Эта часть определенно работает в моих тестах.

6 голосов
/ 26 марта 2010

В Unices вы можете использовать termios.tcflush():

import time
import subprocess
import sys
from termios import tcflush, TCIOFLUSH

alarm1 = int(raw_input("How many minutes (alarm1)? "))

while (1):
    time.sleep(60*alarm1)
    print "Alarm1"
    sys.stdout.flush();
    tcflush(sys.stdin, TCIOFLUSH)
    doit = raw_input("Continue (Y/N)?[Y]: ")
    print "Input",doit
    if doit == 'N' or doit=='n':
        print "Exiting....."
        break
3 голосов
/ 26 марта 2010
#!/usr/bin/python

import time
import subprocess
import sys
import os, select

alarm1 = int(raw_input("How many minutes (alarm1)? "))

while (1):
    time.sleep(3*alarm1)
    print "Alarm1"
    sys.stdout.flush()
    while select.select([sys.stdin.fileno()], [], [], 0.0)[0]:
        os.read(sys.stdin.fileno(), 4096)
    doit = raw_input("Continue (Y/N)?[Y]: ")
    print "Input",doit
    if doit == 'N' or doit=='n':
        print "Exiting....."
        break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...