在Python的sys.stdout解释器中默认启用输出缓冲吗?
如果答案是肯定的,那么有哪些方法可以禁用它?
目前的建议:
使用-u命令行开关
包装系统。每次写入后刷新的对象中的标准输出
设置PYTHONUNBUFFERED env变量
sys。Stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
是否有其他方法在sys/sys中设置全局标志。在执行期间以编程方式Stdout ?
如果只是想在使用打印的特定写入之后刷新,请参阅如何刷新打印函数的输出?。
# 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)
工作人员:“塞巴斯蒂安”,在Python邮件列表的某个地方。
(我已经发表了一条评论,但不知怎么弄丢了。所以,再次:)
正如我注意到的,CPython(至少在Linux上)的行为取决于输出的位置。如果转到tty,则输出在每个“\n”之后被刷新。
如果它进入管道/进程,那么它将被缓冲,您可以使用基于flush()的解决方案或上面推荐的-u选项。
稍微与输出缓冲相关:
如果对输入中的行进行迭代
对于sys.stdin中的行:
...
那么CPython中的for实现将收集一段时间的输入,然后为一堆输入行执行循环体。如果脚本要为每个输入行写入输出,这可能看起来像输出缓冲,但实际上是批处理,因此,flush()等技术都无法帮助实现这一点。
有趣的是,在pypy中没有这种行为。
为了避免这种情况,您可以使用
而真正的:
行= sys.stdin.readline ()
...
重写sys的只写方法是可能的。带有一个调用flush的Stdout。建议的方法实现如下所示。
def write_flush(args, w=stdout.write):
w(args)
stdout.flush()
w参数的默认值将保留原来的写入方法引用。定义了write_flush之后,可能会覆盖原来的写操作。
stdout.write = write_flush
代码假设stdout是从sys import stdout以这种方式导入的。
在Python 3中,你可以修补打印函数,以始终发送flush=True:
_orig_print = print
def print(*args, **kwargs):
_orig_print(*args, flush=True, **kwargs)
正如在评论中指出的,你可以通过functools.partial将flush形参绑定到一个值来简化这一点:
print = functools.partial(print, flush=True)