将程序的latin-1编码输出管道化为Python 3脚本

时间:2011-03-15 00:34:29

标签: python python-3.x stdin

我想用Python 3脚本(在Linux上)逐行处理正在运行的程序的输出(想象tail -f)。

程序输出,通过管道输出到脚本,用latin-1编码,因此,在Python 2中,我使用codecs模块正确解码sys.stdin的输入:< / p>

#!/usr/bin/env python
import sys, codecs

sin = codecs.getreader('latin-1')(sys.stdin)
for line in sin:
    print '%s "%s"' % (type (line), line.encode('ascii','xmlcharrefreplace').strip())

这有效:

<type 'unicode'> "Hi! &#246;&#228;&#223;"
...

然而,在Python 3中,sys.stdin.encodingUTF-8,如果我只是从stdin中天真地读过:

#!/usr/bin/env python3
import sys

for line in sys.stdin:
    print ('type:{0} line:{1}'.format(type (line), line))

我收到此错误:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xf6 in position 4: invalid start byte

如何在Python 3中读取通过管道传输到stdin的非UTF-8文本数据?

2 个答案:

答案 0 :(得分:3)

import sys
import io

with io.open(sys.stdin.fileno(),'r',encoding='latin-1') as sin:
    for line in sin:
        print ('type:{0} line:{1}'.format(type (line), line))

产量

type:<class 'str'> line:Hi! öäß

答案 1 :(得分:2)

请查看文档中的此链接:sys.stdin。相关部分是:

  

默认情况下,标准流处于文本模式。要将二进制数据写入或读取,请使用基础二进制缓冲区。例如,要将字节写入stdout,请使用sys.stdout.buffer.write(b'abc')。使用io.TextIOBase.detach()流可以默认为二进制。此函数将stdin和stdout设置为binary:

def make_streams_binary():  
    sys.stdin = sys.stdin.detach()  
    sys.stdout = sys.stdout.detach()

执行此操作后,您可以将二进制输入编码为您想要的任何编码。


另见这篇文章: How to set sys.stdout encoding in Python 3?
该帖子的建议是使用:

sys.stdin = codecs.getreader("utf-8")(sys.stdin.detach())