为什么在循环中使用睡眠时不能暂停Python中的打印?

Sta*_*tec 9 python python-3.x

这段代码:

import time
for i in range(10):
    print(i)
    time.sleep(.5)
Run Code Online (Sandbox Code Playgroud)

使我的电脑挂起5秒钟,然后打印0-9,而不是每半秒打印一个数字.难道我做错了什么?

the*_*eye 15

print默认情况下,打印到内部sys.stdout并在内部缓冲要打印的输出.

输出是否缓冲通常由文件确定,但如果flush关键字参数为true,则强制刷新流.

版本3.3中已更改:添加了flush关键字参数.

引用sys.stdout文件,

交互式时,标准流是行缓冲的.否则,它们像常规文本文件一样进行块缓冲.

因此,在您的情况下,您需要显式刷新,就像这样

import time
for i in range(10):
    print(i, flush=True)
    time.sleep(.5)
Run Code Online (Sandbox Code Playgroud)

好的,围绕这个缓冲有很多困惑.让我尽可能地解释一下.

首先,如果您在终端中尝试此程序,它们会进行行缓冲(这基本上意味着,无论何时遇到换行符,都会将缓冲数据发送到stdout),默认情况下.因此,您可以在Python 2.7中重现此问题,就像这样

>>> import time
>>> for i in range(10):
...     print i,
...     time.sleep(.5)
... 
Run Code Online (Sandbox Code Playgroud)

在Python 3.x中,

>>> for i in range(10):
...     print(i, end='')
...     time.sleep(.5)
Run Code Online (Sandbox Code Playgroud)

我们通过,end=''因为默认end值是\n,根据print文档,

print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Run Code Online (Sandbox Code Playgroud)

由于默认设置end会中断行缓冲,因此数据将立即发送stdout.

重现此问题的另一种方法是将OP给出的实际程序存储在一个文件中并使用Python 3.x解释器执行,您将看到stdout内部缓冲数据并等待程序完成打印.

  • @vks这正是重点.循环中的代码运行10次,写入`stdout`的所有数据都被缓冲.所以没有任何东西被打印5秒(10*0.5秒),最后当程序退出时,`stdout`被刷新. (3认同)
  • @vks不,不是.我能够重现这个问题.不要使用行缓冲的交互式shell,尝试将代码写入文件并使用解释器执行它. (2认同)