Python 禁用输出缓冲
在Python的解释器中,Python 禁用输出缓冲,python,stdout,buffered,Python,Stdout,Buffered,在Python的解释器中,sys.stdout是否默认启用了输出缓冲 如果答案是肯定的,那么禁用它的所有方法是什么 迄今为止的建议: 使用-u命令行开关 将sys.stdout包装在一个对象中,该对象在每次写入后都会刷新 设置pythonunbufferenv变量 sys.stdout=os.fdopen(sys.stdout.fileno(),'w',0) 在执行过程中,是否有其他方法以编程方式在sys/sys.stdout中设置一些全局标志?来自: 您可以跳过整个缓冲区 使用“python-
sys.stdout
是否默认启用了输出缓冲
如果答案是肯定的,那么禁用它的所有方法是什么
迄今为止的建议:
-u
命令行开关sys.stdout
包装在一个对象中,该对象在每次写入后都会刷新pythonunbuffer
env变量sys.stdout=os.fdopen(sys.stdout.fileno(),'w',0)
sys
/sys.stdout
中设置一些全局标志?来自:
您可以跳过整个缓冲区
使用“python-u”的python进程
(或#!/usr/bin/env python-u等)或
设置环境变量
蟒蛇缓冲
您还可以将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'
是的
您可以使用“-u”开关在命令行上禁用它
或者,您可以在每次写入时调用sys.stdout上的.flush()(或者使用自动执行此操作的对象包装它)是的,默认情况下会启用它。在调用python时,可以使用命令行上的-u选项禁用它。获得无缓冲输出的一种方法是使用
sys.stderr
而不是sys.stdout
,或者只需调用sys.stdout.flush()
来显式强制执行写入
您可以通过执行以下操作轻松重定向打印的所有内容:
import sys; sys.stdout = sys.stderr
print "Hello World!"
或仅为特定的打印语句重定向:
print >>sys.stderr, "Hello World!"
要重置标准输出,您只需执行以下操作:
sys.stdout = sys.__stdout__
您可以创建一个无缓冲文件并将该文件分配给sys.stdout
import sys
myFile= open( "a.log", "w", 0 )
sys.stdout= myFile
您无法神奇地更改系统提供的标准输出;因为它是由操作系统提供给python程序的
# 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邮件列表的某个地方。您还可以使用fcntl更改fly中的文件标志
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)
如果不保存旧的sys.stdout,disable_stdout_buffering()不是幂等函数,多次调用将导致如下错误:
Traceback (most recent call last):
File "test/buffering.py", line 17, in <module>
print "hello"
IOError: [Errno 9] Bad file descriptor
close failed: [Errno 9] Bad file descriptor
(附加到gc.garbage并不是一个好主意,因为它是放置不可冻结循环的地方,您可能需要检查这些循环。)可以正常工作的变体(至少在win32上;python 2.7,ipython 0.12)随后调用(多次):
def DisOutBuffering():
如果sys.stdout.name=='':
sys.stdout=os.fdopen(sys.stdout.fileno(),'w',0)
如果sys.stderr.name='':
sys.stderr=os.fdopen(sys.stderr.fileno(),'w',0)
我宁愿把我的答案写进或写进,但因为它们被标记为这一答案的副本(我不同意),我将在这里回答
由于Python 3.3,print()支持关键字参数“flush”():
(我发布了一条评论,但不知怎么弄丢了。所以,还是:)
正如我所注意到的,CPython(至少在Linux上)的行为因输出的位置而异。如果它转到tty,则在每个“\n”
如果它进入管道/进程,那么它将被缓冲,您可以使用基于flush()
的解决方案或上面推荐的-u选项
与输出缓冲略微相关:
如果您使用
用于系统标准中的行:
然后CPython中的for实现将收集一段时间的输入,然后执行一组输入行的循环体。如果您的脚本即将为每个输入行写入输出,这可能看起来像输出缓冲,但实际上是批处理,因此,flush()
等技术都不会有帮助。
有趣的是,在pypy中没有这种行为。
要避免这种情况,您可以使用
为True时:
line=sys.stdin.readline()
……在Python2.6、2.7和3.2中执行以下工作:
import os
import sys
buf_arg = 0
if sys.version_info[0] == 3:
os.environ['PYTHONUNBUFFERED'] = '1'
buf_arg = 1
sys.stdout = os.fdopen(sys.stdout.fileno(), 'a+', buf_arg)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'a+', buf_arg)
您还可以使用以下实用程序运行Python:
stdbuf-oL python
这与克里斯托夫·苏萨的回答有关,但我还不能发表评论
使用Python3的flush
关键字参数以始终具有无缓冲输出的直接方法是:
import functools
print = functools.partial(print, flush=True)
之后,打印将始终直接刷新输出(除非给出了flush=False
)
注意,(a)这只回答了部分问题,因为它没有重定向所有输出。但是我想在python中,print
是为stdout
/stderr
创建输出的最常用方法,因此这两行可能涵盖了大多数用例
注意(b)它只在您定义它的模块/脚本中起作用。这在编写模块时很好,因为它不会弄乱sys.stdout
Python2不提供flush
参数,但您可以模拟此处所述的Python3-typeprint
函数。只可以用调用flush
的方法覆盖sys.stdout
的写入方法。建议的方法实现如下
def write_flush(args, w=stdout.write):
w(args)
stdout.flush()
w
参数的默认值将保留原始的write
方法引用。定义write\u flush
后,可能会覆盖原始的write
stdout.write = write_flush
该代码假定以这种方式从sys import stdout导入stdout
在Python 3中,您可以对print函数进行monkey-patch,以始终发送flush=True:
_orig_print = print
def print(*args, **kwargs):
_orig_print(*args, flush=True, **kwargs)
正如注释中指出的,您可以通过functools.partial
将flush参数绑定到一个值来简化此过程:
print = functools.partial(print, flush=True)
原来的sys.stdout仍然可以作为sys.\u stdout\uuuu使用。以防万一你需要它=)#/usr/bin/env python-u
不起作用!!为了避免继承,请参见\uuuu getattr\uuuu
?!我注意到,输出缓冲的工作方式不同
def write_flush(args, w=stdout.write):
w(args)
stdout.flush()
stdout.write = write_flush
_orig_print = print
def print(*args, **kwargs):
_orig_print(*args, flush=True, **kwargs)
print = functools.partial(print, flush=True)