【问题标题】:Why print in Python doesn't pause when using sleep in a loop?为什么在循环中使用睡眠时 Python 中的打印不会暂停?
【发布时间】:2015-04-28 11:01:40
【问题描述】:

这段代码:

import time
for i in range(10):
    print(i)
    time.sleep(.5)

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

【问题讨论】:

  • 我对python不太了解,但是你需要打印一个换行符才能将输出打印到控制台吗?
  • 不,正如我所说,这确实打印了数字,只是在它们之间没有延迟。
  • 它在我的电脑上运行良好
  • 我的工作也很好。你可能有缩进问题?作为记录,我正在使用 python3.4
  • @Startec 我能够重现这个问题,我已经在我的回答中解释了解决方案,请检查。其他的,不要使用交互式shell,它是行缓冲的,尝试将代码写入文件并使用解释器执行。

标签: python python-3.x


【解决方案1】:

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

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

3.3 版更改:添加了 flush 关键字参数。

引用sys.stdout's documentation

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

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

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

好的,这个缓冲有很多混乱。让我尽可能解释。

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

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

在 Python 3.x 中,

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

我们通过end='',因为根据print's documentation,默认end 值为\n

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

由于默认end打破了行缓冲,数据将立即发送到stdout

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

【讨论】:

  • @vks 不,不是。我能够重现该问题。不要使用交互式shell,它是行缓冲的,尝试将代码写入文件并使用解释器执行。
  • @vks 因为交互式 shell 是行缓冲的,所以你看不出区别。它会立即打印。
  • @vks 这正是重点。循环中的代码运行了10次,所有写入stdout的数据都被缓冲了。所以在 5 秒(10 * 0.5 秒)内什么都没有打印出来,最后当程序退出时,stdout 被刷新。
【解决方案2】:

试试这个:

for i in range(10):
        sys.stdout.write('\r' + str(i))
        time.sleep(.5)

这里'/r'是回车,它把光标再次带到第一位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2011-11-22
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多