select
模块提供了一个名为 select
的函数,它可以实现您要寻找的功能。 select.select
接受三个参数:
select.select(rlist, wlist, xlist)
每个参数都应该是文件描述符列表(例如[sys.stdin]
),然后等待特定的IO操作可用。IO操作包括给定文件描述符上的r读取,w写入或其他x异常。它返回一个元组
,其中包含准备就绪的文件描述符对应的列表。
因此,如果在sys.stdin
中有输入等待,则函数将像这样运行:
>>> import select
>>> import sys
>>>
>>> select.select([sys.stdin], [], [])
([sys.stdin], [], [])
>>>
单独使用这个函数并不能解决你的问题,因为默认情况下该函数会等待IO操作可用。然而,值得注意的是,select.select
有一个可选的timeout
参数,表示它在放弃之前等待多长时间。我们只需要将超时设置为零,就可以在不阻塞程序流的情况下检查输入。
让我们看一个例子,在sys.stdin
中没有等待输入:
>>> import select
>>> import sys
>>>
>>> timeout = 0
>>> select.select([sys.stdin], [], [], timeout)
([], [], [])
>>>
知道我们只想要那个元组的第一个元素(输入流),我们就可以编写有用的 if 语句了:
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
print('Input is waiting to be read.')
这意味着清除输入流只需要一些迭代:
while sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
sys.stdin.readline()
当然,我们可以将其用于任何输入流上,现在将其放入一个函数中:
def clear_input(stream, timeout=0):
'''Takes an input stream and discards each line in the buffer.
The given timeout denotes how long in seconds to wait for
further input when none is available.
'''
while stream in select.select([stream], [], [], timeout)[0]:
stream.readline()
那么让我们演示一下如何实现你在问题中所要求的功能:
import select
import sys
import time
def clear_input(stream, timeout=0):
while stream in select.select([stream], [], [], timeout)[0]:
stream.readline()
if __name__ == '__main__':
print('Type some lines now. They will be ignored.')
time.sleep(5)
print('Clearing input.')
clear_input(sys.stdin)
user_input = raw_input('Please give some fresh input: ')
print(user_input)
clear_input
函数可以作为一种非阻塞方式来清除输入流,应该适用于 Python2 和 Python3。
fflush(stdin)
是未定义行为。 - Sourav Ghosh./myprog </dev/random
;它会看到stdin流的末尾吗? - joopapt-get
程序是有意这样做的。请参见Prevent sudo, apt-get, etc. from swallowing pasted input to STDIN。 - Mark Plotnick