在 python 中,如何检查标准输入流 (sys.stdin) 的末尾并对此做一些特殊的事情

In python, how to check the end of standard input streams (sys.stdin) and do something special on that

提问人:YaOzI 提问时间:6/7/2014 最后编辑:CommunityYaOzI 更新时间:9/30/2023 访问量:42497

问:

我想做这样的事情:

for line in sys.stdin:
    do_something()
    if is **END OF StdIn**:
        do_something_special()

经过几次尝试,现在我正在这样做:

while True:
    try:
        line = sys.stdin.next()
        print line,
    except StopIteration:
        print 'EOF!'
        break

或者用这个:

while True:
    line = sys.stdin.readline()
    if not line:
        print 'EOF!'
        break
    print line,

我认为上述两种方式非常相似。我想知道有没有更优雅(pythonic)的方法可以做到这一点?


早期失败的尝试:

我首先尝试从循环内部或外部捕获异常,但我很快意识到,由于异常是内置在循环本身中的,因此以下两个代码片段都不起作用。StopIterationforStopIterationfor

try:
    for line in sys.stdin:
        print line,
except StopIteration:
    print 'EOF'

for line in sys.stdin:
    try:
        print line,
    except StopIteration:
        print 'EOF'
Python stdin eof

评论

0赞 Codism 6/30/2017
你找到问题的答案了吗?我在 2.7 中面临同样的问题。应该有一个简单的解决方案。

答:

29赞 user2357112 6/7/2014 #1
for line in sys.stdin:
    do_whatever()
# End of stream!
do_whatever_else()

就是这么简单。

评论

1赞 Codism 6/30/2017
我在python 2.7 / windows / debian中尝试了这个;命中“Enter”后,循环体不会立即启动,这没有用。但是,代码在 Python 3 中按预期工作。
0赞 user2357112 6/30/2017
@Codism:这听起来像是输入缓冲,无论是在文件对象实现中还是在操作系统级别。这很正常。如果你想要不同的缓冲行为,有一些方法可以得到它,但这不是这个问题的主题。
1赞 meawoppl 9/18/2017
如果输入不以换行符结尾,这将永远挂起。
2赞 user2357112 9/18/2017
@meawoppl:无法复制。只要输入流实际结束(而不仅仅是保持打开状态),循环就应该终止。如果您从终端运行它,您可能需要按 Ctrl-D 或其他方式来发出输入结束的信号。
0赞 Roman M 2/5/2018
@user2357112请添加注释,这仅适用于 Python 3
15赞 KIM Taegyoon 7/15/2015 #2

使用 try/except。输入

读取 EOF 时,将引发 EOFError。

while True:
    try:
        s=input("> ")
    except EOFError:
        print("EOF")
        break
0赞 CervEd 9/30/2023 #3

使用迭代器

from typing import Iterable
def last_line(itr: Iterable[str]) -> (bool, str):
    last = None
    for line in itr:
        if last is not None:
            yield False, last
        last = line
    if last is not None:
        yield True, last

喜欢这个

for last, line in last_line(sys.stdin):
    if not last:
        do_something()
    else:
        do_something_special()