print() 函数中的 `flush` 参数是什么意思?

76

print()函数有一个布尔类型的可选参数flush,默认值为False。

文档中指出此参数用于强制刷新流。

我不理解"flushing"的概念。这里所说的"flushing"是什么?流的"flushing"是什么意思?


2
我相信这会强制将所有数据立即打印到控制台并将挂起的打印缓冲区“刷新”到实际控制台。 - Christian Stewart
2
@ChristianStewart 我不太理解这个概念。你能给我举一个实际的例子吗? - Santosh Kumar
2
@ChristianStewart:我不确定这总是适用的,我记得有些情况你需要有一个换行符来进行“自动刷新”。这可能取决于底层操作系统。 - Anthon
4个回答

50

通常情况下,输出到文件或控制台的内容都会被缓存,文本输出至少要等到你打印一个换行符才会输出。flush功能可以确保所有已经被缓存的输出都被发送到目标位置。

例如,在获取用户输入之前,如果我需要创建一个用户提示,比如是否继续(Y/n):,我就会用到这个功能。

在Ubuntu 12.4上使用Python 2.7可以模拟此功能:

from __future__ import print_function

import sys
from time import sleep

fp = sys.stdout
print('Do you want to continue (Y/n): ', end='')
# fp.flush()
sleep(5)

如果您运行此代码,您会发现提示信息直到程序休眠结束并退出后才会显示。如果您取消注释flush函数的那一行,你将可以看到提示信息,但要等待5秒钟程序才能完成。


3
我需要一个示例来说明它与默认设置有何不同。 - Santosh Kumar
1
希望这能对你有所帮助。@Yuushi的解释比我的更详细,也尝试看看它是否对你有帮助。 - Anthon
2
好的!我明白了概念。我制作了一个更加交互式的脚本来演示:https://gist.github.com/santosh/5235922 - Santosh Kumar
@Anthon,这是我得到的最好的答案之一,谢谢。 - storenth

45

需要理解的几个概念,包括缓冲IO和非缓冲IO。概念相对简单 - 对于缓冲IO,会保留一个内部缓冲区。只有当这个缓冲区满了(或者达到换行符之类的其他事件)才会“刷新”输出。对于非缓冲IO,每次输出都会逐个字符地进行。

大多数IO函数都属于缓冲类别,主要是基于性能原因:一次写入一块内容速度更快(所有I/O函数最终都会变成某种系统调用,这些调用很费时)。

flush允许手动选择何时将这个内部缓冲区写入 - 调用flush将写入缓冲区中的任何字符。通常情况下不需要使用它,因为流会自行处理。但是,在某些情况下,您可能希望确保在继续之前输出某些内容 - 这就是使用flush()的情况。


7

我们有两个完美的答案:

Anthon让人很清楚地理解到,基本上,在下一行完成之前,打印行在技术上不会运行(print)

实际上,该行确实运行,只是在下一行完成运行之前保持未缓冲。

这可能会对某些人造成问题,他们在运行print函数后使用sleep函数,期望在sleep函数开始之前看到它打印出来。

那么我为什么要添加另一个答案呢?

未来已经到来,我想花点时间向您介绍一下:

from __future__ import print_function

首先,我相信这是一种内部幽默,旨在展示一个错误:Future未定义^_^


我现在正在查看PyCharm的文档,看起来他们添加了一个刷新方法,内置在print函数本身中,看一下这个:

def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
"""
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file:  a file-like object (stream); defaults to the current sys.stdout.
sep:   string inserted between values, default a space.
end:   string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
"""
pass

在这里输入图片描述


那么我们可能可以使用:(不确定参数的使用顺序是否应该相同)

from __present__ import print_function

from time import sleep

print('Hello World', flush=True)

sleep(5)

或者这个:
print('Hello World', file=sys.stdout , flush=True)

Anthon说:

如果你运行这个程序,你会发现提示字符串不会显示,直到睡眠结束并且程序退出。如果你取消注释flush的那一行,你会看到提示,然后必须等待5秒钟才能完成程序。

因此,让我们将其转换为我们当前的情况:

如果你运行这个程序,你会看到提示,然后必须等待5秒钟才能完成程序。如果你将带有flush的那一行改为flush=False,你会发现提示字符串不会显示,直到睡眠结束并且程序退出。


顺便提一下,这份文档来自于 PyCharm 的 buildins.py 文件。 我知道 flush 不是 print 可接受的有效参数。 请测试并让我知道结果,这样我就可以更新我的答案以匹配当前的正确状态。 - orr burgel

4

一个实际的例子来理解带有和不带有flush参数的print()

import time

for i in range(5):
    print(i, end=" ", flush=True)  # Print numbers as soon as they are generated
    # print(i, end=" ", flush=False)  # Print everything together at the end
    time.sleep(0.5)

print("end")

您可以注释/取消注释print行,以检查它如何影响输出的方式。

这与被接受的答案类似,只是更简单,并适用于Python 3。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接