有许多方法可以在Python中设置输出缓冲:Disable output buffering
让我感到好奇的是,我怎么知道输出缓冲真的已经关闭了?检查它的最佳和最简单的方法是什么?
答案 0 :(得分:1)
试试这个:$ python myscript.py | cat
如果它没有缓冲,脚本的输出将立即显示在您的终端上。否则它将由cat
缓冲,直到发生刷新,由脚本触发或完成时。
答案 1 :(得分:0)
经过一些实验,我发现这个方法可以区分python是否在stdout上缓冲:
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
我在CMD,MinGW和Git Bash的Windows上测试过它。关键测试是Git Bash,它默认为缓冲,除非你用python -u
调用它,在这种情况下它是无缓冲的(Cmd and Git bash have a different result when run a Python code)
此检查可用于终端脚本的开头,以警告用户是否可能受到延迟输出的影响,例如:如果没有刷新,则从print语句开始。
答案 2 :(得分:0)
我已经在Linux上使用Python 3.8测试了stdout缓冲,发现Python3的输出缓冲区可以检测它是否正在终端(“ TTY”)上运行,在这种情况下,打印功能的输出会立即显示,否则输出将延迟到缓冲区已满或脚本退出之前。例如,如果通过管道输出标准输出,它将确定它不在TTY。 (对不起,我不知道在Windows上会发生什么。)
当然,可以使用“ flush = True”打印参数来防止此输出延迟。也可以通过使用Python3的“ -u”命令行参数禁用缓冲,或者通过设置外壳环境变量PYTHONUNBUFFERED = true来防止这种情况,在这种情况下,该缓冲将被直接FileIO代替。
所有这些都可以在Python3中通过查询sys.stdout.buffer进行检测,如下所示:
#!/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
编辑:并且还可以通过以下shebang禁用缓冲(假设脚本名称在shell命令中未以“ python3”作为前缀。)
#!/usr/bin/env -S python3 -u