为什么即使在刷新和使用 -u 时,python 也会继续缓冲标准输出?

Pat*_*k B 4 python stdout pipe buffering

$ cat script.py
import sys

for line in sys.stdin:
    sys.stdout.write(line)
    sys.stdout.flush()

$ cat script.py - | python -u script.py
Run Code Online (Sandbox Code Playgroud)

输出是正确的,但只有在我按下 Ctrl-D 后它才开始打印,而以下内容立即开始打印:

$ cat script.py - | cat
Run Code Online (Sandbox Code Playgroud)

这让我认为缓冲不是来自 cat.

我设法让它工作:

for line in iter(sys.stdin.readline, ""):
Run Code Online (Sandbox Code Playgroud)

正如这里所解释的:Streaming Pipes in Python,但我不明白为什么前一个解决方案不能按预期工作。

Ada*_*man 5

Python 手册页揭示了您问题的答案:

   -u     Force stdin, stdout and stderr to be totally unbuffered.  On systems where it matters, also put stdin, stdout and stderr in binary mode.  Note that
          there  is  internal  buffering  in  xreadlines(),  readlines()  and file-object iterators ("for line in sys.stdin") which is not influenced by this
          option.  To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.
Run Code Online (Sandbox Code Playgroud)

也就是说:文件对象迭代器的内部缓冲是罪魁祸首(并且它不会随 -u 一起消失)。