在 Python 中有很多种关闭输出缓冲的方法:禁用输出缓冲
让我感到好奇的是,如何知道输出缓冲已经真正地关闭了?最简单和最好的检查方式是什么?
$ python myscript.py | cat
如果是非缓冲的,则脚本输出会立即显示在终端上。否则,它将被cat
缓冲,直到刷新发生,可以由脚本触发或者脚本完成时自动触发。#!/usr/bin/env python3
import sys
print("Name: ", type(sys.stdout.buffer).__name__)
print("TTY? ", sys.stdout.buffer.isatty())
$ myscript.py # Displays immediately
Name: BufferedWriter
TTY? True
$ myscript.py | tee # Waits for script exit because of pipe
Name: BufferedWriter
TTY? False
$ python3 -u myscript.py # Displays immediately
Name: FileIO
TTY? True
$ python3 -u myscript.py | tee # Also displays immediately despite pipe
Name: FileIO
TTY? False
编辑:如果脚本名称在shell命令中没有以“python3”为前缀,也可以使用以下shebang禁用缓冲。
#!/usr/bin/env -S python3 -u
经过一些实验,我发现这种方法可以区分Python是否在标准输出上进行缓冲:
import sys
def is_stdout_buffered():
# Print a single space + carriage return but no new-line (should have no visible effect)
print " \r",
# If the file position is a positive integer then stdout is buffered
try:
pos = sys.stdout.tell()
if pos > 0:
return True
except IOError: # In some terminals tell() throws IOError if stdout is unbuffered
pass
return False
python -u
调用它,则为非缓冲模式(在运行Python代码时,Cmd和Git bash有不同的结果)。
sys
是C模块,你不能做超出接口提供的事情。 - Dmitry Torbasys.stdout.flush()
,无论缓冲是否开启都能正常工作。有些任务可能需要及时刷新,例如查看我的回答 http://stackoverflow.com/questions/39255498/python-cgi-os-system-causing-malformed-header ,但这并不意味着你需要知道数据是否被缓冲。这只是一个有趣的发现,但我认为在那种情况下你可以进行实验。 - Dmitry Torba