print() 的 `flush` 有什么作用?

79 投票
5 回答
46355 浏览
提问于 2025-04-17 20:11

print()这个函数里,有一个可选的布尔参数叫flush,默认值是False。

文档上说这个参数是用来强制清空输出流的。

我不太明白“清空”的概念。这里的“清空”是什么意思?输出流的清空又是什么?

5 个回答

6

这里有两个很棒的回答,

Anthon 讲得非常清楚,基本上,打印的那一行在下一行执行完之前是不会真正运行的 (print)

从技术上讲,这一行确实是运行的,只是它会保持在未缓冲状态,直到下一行执行完。

这可能会导致一些人出现错误,尤其是那些在运行 print 函数后使用 sleep 函数的人,他们期待在 sleep 函数开始之前就能看到打印的内容。

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

未来已经到来,我想花点时间来更新你们:

from __future__ import print_function

首先,我认为这是一个内部玩笑,想要展示一个错误:未来未定义 ^_^


我现在正在查看 PyCharm 的文档,似乎他们在打印函数内部添加了一个刷新方法,看看这个:

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 所说:

如果你运行这个,你会看到提示字符串在 sleep 结束和程序退出之前不会显示。如果你取消注释带有刷新功能的那一行,你会看到提示,然后需要等 5 秒钟程序才能完成。

那么我们就把这个转换到我们当前的情况:

如果你运行这个,你会看到提示,然后需要等 5 秒钟程序才能完成。如果你把带有刷新功能的那一行改为 flush=False,你会看到提示字符串在 sleep 结束和程序退出之前不会显示。

46

这里有几个概念需要了解。首先是“缓冲输入输出”和“无缓冲输入输出”的区别。这个概念其实很简单——在缓冲输入输出中,有一个内部的缓冲区,只有当这个缓冲区满了(或者发生其他事件,比如遇到换行符)时,输出才会被“刷新”。而无缓冲输入输出则是每次输出一个字符,立刻就会执行。

大多数输入输出函数都属于缓冲类型,主要是为了提高性能:一次写入一大块数据要快得多(所有的输入输出函数最终都会转化为某种系统调用,而这些调用是比较耗费资源的)。

flush这个操作可以让你手动选择什么时候将这个内部缓冲区里的内容写出去——调用flush时,会把缓冲区里的所有字符都写出来。通常情况下,这个操作不是必需的,因为流会自己处理这个问题。不过,有时候你可能想确保某些内容在继续之前被输出,这时候就可以使用flush()这个调用。

52

通常情况下,输出到文件或者控制台的内容是有缓冲的,也就是说,文本输出至少要等到你打印一个换行符才会显示出来。使用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秒钟程序才会结束。

撰写回答