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

Why print in Python doesn't pause when using sleep in a loop?

此代码:

1
2
3
4
import time
for i in range(10):
    print(i)
    time.sleep(.5)

使我的计算机挂起5秒,然后打印出0-9,而不是每半秒打印一个数字。我做错什么了吗?


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

Whether output is buffered is usually determined by file, but if the flush keyword argument is true, the stream is forcibly flushed.

Changed in version 3.3: Added the flush keyword argument.

引用sys.stdout的文件,

When interactive, standard streams are line-buffered. Otherwise, they are block-buffered like regular text files.

所以,在您的情况下,您需要显式地刷新,像这样

1
2
3
4
import time
for i in range(10):
    print(i, flush=True)
    time.sleep(.5)

好吧,这个缓冲区有很多混乱。让我尽可能多地解释一下。

首先,如果您在终端中尝试这个程序,默认情况下,它们执行行缓冲(这基本上意味着,每当遇到换行符时,都会将缓冲的数据发送到stdout。所以,您可以在python 2.7中重现这个问题,如下所示

1
2
3
4
5
>>> import time
>>> for i in range(10):
...     print i,
...     time.sleep(.5)
...

在python 3.x中,

1
2
3
>>> for i in range(10):
...     print(i, end='')
...     time.sleep(.5)

我们通过end='',因为根据print的文件,默认的end值为

1
2
print(*objects, sep=' ', end='
'
, file=sys.stdout, flush=False)

由于默认的end中断了线路缓冲,数据将立即发送到stdout

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


试试这个:

1
2
3
4
for i in range(10):
        sys.stdout.write('
'
+ str(i))
        time.sleep(.5)

这里,'/r'是回车,它再次将光标放在第一位。