【问题标题】:How to flush the input stream?如何刷新输入流?
【发布时间】:2010-03-26 02:49:53
【问题描述】:

我正在用 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 上运行它。

【问题讨论】:

  • 你不需要sys.stdout.flush();后面的分号
  • 我的错,你是对的,我不需要分号。修复了代码。
  • “刷新或丢弃所有击键”?你的意思是“阅读并忽略”你不能轻易地“刷新”输入。为什么不做简单而明显的事情:阅读它们并忽略它们?

标签: python


【解决方案1】:

了解您正在使用的操作系统会有所帮助,因为这是一个非常特定于操作系统的问题。例如,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

【讨论】:

  • 我在 Windows xp 中运行它。
  • 那你可能想试试msvcrt模块;请参阅上面的编辑。
【解决方案2】:

来自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 平台。我没有亲自测试过这部分。但除了部分适用于 linux 终端。 termios 模块有一些终端接口功能。 tcflush 可以刷新输入或输出缓冲数据。这部分绝对适用于我的测试。

【讨论】:

  • 为什么 OP 应该相信你的回答? 好的答案将始终解释所做的事情以及为什么以这种方式完成,不仅适用于 OP,而且适用于 SO 的未来访问者。
  • @bub,感谢您的提示。我认为这不需要太多解释。将编辑我的答案
  • 这类似于@Callahad 所拥有的。只是包裹在一个漂亮的'def'中
【解决方案3】:

在 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

【讨论】:

    【解决方案4】:
    #!/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
    

    【讨论】:

    • 我将你的睡眠时间减少到 3 秒,用于测试:)
    • 此代码在 Windows XP 上不起作用。你能解释一下你发送给 select.select() 的各种参数吗?
    • 啊,我不知道你在 Windows 上。这根本不起作用(我看到 /usr/bin/python 并假设。我的错。)选择的文档在这里:docs.python.org/library/select.html 但在 Windows 上它只会绑定到套接字。
    猜你喜欢
    • 2021-08-15
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2020-03-20
    相关资源
    最近更新 更多