在Python 3中将sys.stdout重定向到没有缓冲的文件

时间:2015-09-03 01:29:04

标签: python python-3.x io buffer

我有一个写入日志文件的脚本。在Python 2中,我的快速解决方案允许在日志进行过程中跟踪/查看日志,方法是将sys.stdout分配给缓冲区设置为0的文件对象:

original_stdout = sys.stdout
sys.stdout = open(log_file, 'w', 0)

设置后,脚本函数中的任何print语句都会很好地重定向到日志文件。

在Python 3下运行2to3转换版本会出现以下错误:ValueError: can't have unbuffered text I/O。将上面的'w'更改为'wb'解决了这个问题,因此块的结构是

original_stdout = sys.stdout
sys.stdout = open(log_file, 'wb', 0)
print("{}".format(first_message))

但现在第一个print语句错误TypeError: 'str' does not support the buffer interface。我尝试将字符串显式地转换为字节

print(bytes("{}".format(first_message), "UTF-8"))

但是它产生与以前相同的TypeError

在Python 3中将无缓冲文本写入文件的最简单方法是什么?

3 个答案:

答案 0 :(得分:1)

根据https://docs.python.org/3/library/io.html#raw-i-o处的Python 3.4.3文档和https://docs.python.org/3.5/library/io.html#raw-i-o处的3.5文档,获取无缓冲IO的方法是使用Raw IO,可以在以下位置启用:

f = open("myfile.jpg", "rb", buffering=0)

这意味着“wb”应该适用于写作。

原始IO的详细信息位于https://docs.python.org/3/library/io.html#io.RawIOBasehttps://docs.python.org/3.5/library/io.html#io.RawIOBase,看起来是相同的。

我做了一些测试,发现文本IO的缓冲很严重,可能达到数百行,即使在写入sys.stderr并将错误输出重定向到Windows 7上的文件时也会发生这种情况。我尝试了Raw IO,效果很好! - 打印的每一行都是立即通过尾部-f输出的纯文本。这对我来说在Windows 7上使用Python 3.4.3并使用与GitHub工具捆绑的尾部是有用的:

import time
import sys
f = open("myfile.txt", "ab", buffering=0)
c = 0
while True:
    f.write(bytes("count is " + str(c) + '\n','utf-8'))
    c += 1
    time.sleep(1)

答案 1 :(得分:0)

如果无缓冲意味着将输出立即刷新到磁盘,则可以执行此操作:

original_stdout = sys.stdout
sys.stdout = open(log_file, 'w')
print(log_message, flush=True)

由于print现在是一流的功能,您还可以指定要打印的file,例如:

fd = open(log_file, 'w')
print(log_message, file=fd, flush=True)

答案 2 :(得分:0)

问题似乎在于打开文件的方式 -

open(log_file, 'w', 0)

来自Python 3.x documentation -

  

打开(文件,模式=' r',缓冲= -1 ,编码=无,错误=无,换行=无,closefd = True,开启者=无)

open()的第三个参数确定文件的缓冲模式,0表示没有缓冲。我认为只要使用'wb'代替'w'即可使其发挥作用。

您应该删除0第三个参数,并让open()对文本文件使用默认行缓冲。示例 -

open(log_file, 'w')