禁用输出缓冲

673 投票
16 回答
400333 浏览
提问于 2025-04-11 09:16

在Python的解释器中,sys.stdout的输出缓冲是默认开启的吗?

如果答案是肯定的,那有什么方法可以关闭它呢?

到目前为止的建议有:

  1. 使用 -u 命令行选项
  2. sys.stdout 包装在一个每次写入后都会刷新内容的对象里
  3. 设置环境变量 PYTHONUNBUFFERED
  4. sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

有没有其他方法可以在程序运行时以编程方式设置 syssys.stdout 的一些全局标志呢?


如果你只是想在使用 print 后刷新输出,可以查看 如何刷新print函数的输出?

16 个回答

91
# reopen stdout file descriptor with write mode
# and 0 as the buffer size (unbuffered)
import io, os, sys
try:
    # Python 3, open as binary, then wrap in a TextIOWrapper with write-through.
    sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), 'wb', 0), write_through=True)
    # If flushing on newlines is sufficient, as of 3.7 you can instead just call:
    # sys.stdout.reconfigure(line_buffering=True)
except TypeError:
    # Python 2
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

感谢:“Sebastian”,在某个Python邮件列表上。

232

我本来想把我的回答放在如何刷新Python打印函数的输出?或者Python的打印函数在调用时刷新缓冲区?这两个问题里,但因为这两个问题被标记为重复(我不同意这个说法),所以我就在这里回答了。

从Python 3.3开始,print()函数支持一个叫“flush”的参数(查看文档):

print('Hello World!', flush=True)
522

来自 Magnus Lycka 在一个邮件列表上的回答

你可以通过使用 python -u 命令,或者设置环境变量 PYTHONUNBUFFERED,来让整个 Python 进程跳过缓冲区。

你也可以用其他的流,比如一个包装器,来替换 sys.stdout,这样每次调用后都会进行刷新。

class Unbuffered(object):
   def __init__(self, stream):
       self.stream = stream
   def write(self, data):
       self.stream.write(data)
       self.stream.flush()
   def writelines(self, datas):
       self.stream.writelines(datas)
       self.stream.flush()
   def __getattr__(self, attr):
       return getattr(self.stream, attr)

import sys
sys.stdout = Unbuffered(sys.stdout)
print 'Hello'

撰写回答