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

如果答案是肯定的,那么有哪些方法可以禁用它?

目前的建议:

使用-u命令行开关 包装系统。每次写入后刷新的对象中的标准输出 设置PYTHONUNBUFFERED env变量 sys。Stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

是否有其他方法在sys/sys中设置全局标志。在执行期间以编程方式Stdout ?


如果只是想在使用打印的特定写入之后刷新,请参阅如何刷新打印函数的输出?。


当前回答

您还可以使用fcntl动态更改文件标志。

fl = fcntl.fcntl(fd.fileno(), fcntl.F_GETFL)
fl |= os.O_SYNC # or os.O_DSYNC (if you don't care the file timestamp updates)
fcntl.fcntl(fd.fileno(), fcntl.F_SETFL, fl)

其他回答

变种,工作不崩溃(至少在win32;Python 2.7, ipython 0.12)然后随后调用(多次):

def DisOutBuffering():
    if sys.stdout.name == '<stdout>':
        sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

    if sys.stderr.name == '<stderr>':
        sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', 0)

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

You can skip buffering for a whole python process using python -u or by setting the environment variable PYTHONUNBUFFERED. You could also replace sys.stdout with some other stream like wrapper which does a flush after every call. 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'

是的,它是。

您可以在命令行上使用“-u”开关禁用它。

或者,您可以在sys. flush()上调用。每次写入时的Stdout(或使用自动执行此操作的对象将其包装)

(我已经发表了一条评论,但不知怎么弄丢了。所以,再次:)

正如我注意到的,CPython(至少在Linux上)的行为取决于输出的位置。如果转到tty,则输出在每个“\n”之后被刷新。 如果它进入管道/进程,那么它将被缓冲,您可以使用基于flush()的解决方案或上面推荐的-u选项。 稍微与输出缓冲相关: 如果对输入中的行进行迭代 对于sys.stdin中的行: ...

那么CPython中的for实现将收集一段时间的输入,然后为一堆输入行执行循环体。如果脚本要为每个输入行写入输出,这可能看起来像输出缓冲,但实际上是批处理,因此,flush()等技术都无法帮助实现这一点。 有趣的是,在pypy中没有这种行为。 为了避免这种情况,您可以使用

而真正的: 行= sys.stdin.readline () ...

我宁愿把我的答案放在如何刷新打印功能的输出?或者在Python的print函数中,当它被调用时,会刷新缓冲区?,但由于它们被标记为这一个的副本(我不同意),我将在这里回答它。

从Python 3.3开始,print()支持关键字参数"flush"(参见文档):

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