这两种使用 `sys.stdin` 读取 Python 行的方法有什么区别?

What is the difference between these two ways to read lines in Python with `sys.stdin`?

我认为我不了解使用 sys.stdin 从输入中读取行的方法。

有什么区别

import sys
while True:
    foo(sys.stdin.readline())

import sys
for line in sys.stdin:
    foo(line)

为什么我会选择一个而不是另一个?

此外,我如何获得

的行为
import sys
first_line = sys.readline()
foo(first_line)
while True:
    bar(sys.readline())

通过使用 for-in 循环?具体来说,将第一行与输入中的其他行分开处理的优雅方法是什么? for line in sys.stdin 中的某些东西仍然有效吗?

while True:
    foo(sys.stdin.readline())

此代码将永远循环。如果 sys.stdin 上有一个 EOF——例如,如果输入是从一个文件重定向的,并且已经到达该文件的末尾——那么它将重复调用 foo('')。这可能很糟糕。

for line in sys.stdin:
    foo(line)

当遇到 EOF 时,此代码将停止循环。这个不错。

如果你想以不同的方式处理第一行,你可以在进入循环之前简单地调用一次sys.stdin.readline()

first_line = sys.readline()
foo(first_line)
for line in sys.stdin:
    bar(line)

这里sys.stdin没什么特别的;这只是一个普通的文本文件 object.

for x in iterable: 迭代任何可迭代对象,包括文件 object,只是一遍又一遍地调用 next 直到它引发 StopIteration.

请注意,这意味着如果您想在处理文件的其余部分之前跳过 header 行,您可以在循环之前调用 next(f)

readlinenext 做同样的事情,除了 hint 参数(你没有使用),以及在各种错误条件下发生的事情(这是' 在这里可能无关紧要),以及在 EOF 处发生的情况:readline returns 一个空字符串,next 引发一个 StopIteration.

因此,没有 一般 总体上选择其中之一的理由;归结为在您的特定情况下哪个更具可读性。


如果您的目标是遍历所有行,使用 for 循环会更易读。比较:

for line in sys.stdin:
    do_stuff(line)

while True:
    line = sys.stdin.readline()
    if not line:
        break
    do_stuff(line)

另一方面,如果您的循环涉及使用某些 non-trivial 逻辑读取可变块,readline 通常会更清晰:

while True:
    line = sys.stdin.readline()
    if not line:
        break
    while line.rstrip().endswith('\'):
        line = line.rstrip().rstrip('\') + sys.stdin.readline()
    do_stuff(line)

logical_line = ''
try:
    for line in sys.stdin:
        if logical_line:
            logical_line += line
        if not line.rstrip().endswith('\'):
            do_stuff(logical_line)
            logical_line = ''
except StopIteration:
    if logical_line:
        do_stuff(logical_line)