如何刷新输入流?

23 投票
5 回答
62107 浏览
提问于 2025-04-15 20:52

我正在用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上运行这个程序。

5 个回答

10

在类Unix系统上,你可以使用 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
18

来自 Rosetta Code

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)

这里的try部分是针对Windows系统的。我个人没有测试过这一部分。不过except部分在Linux终端上是可以用的。termios模块有一些终端接口的功能,tcflush可以清空输入或输出的缓冲数据。这部分在我的测试中绝对是有效的。

14

知道你使用的操作系统会很有帮助,因为这个问题跟操作系统关系很大。例如,Kylar的回答在Windows上不管用,因为sys.stdin没有fileno这个属性。

我很好奇,试着用curses写了个解决方案,但这个在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

撰写回答