Python 如何使Popen()正确理解UTF-8?
这是我用Python编写的代码:Python 如何使Popen()正确理解UTF-8?,python,Python,这是我用Python编写的代码: [...] proc = Popen(path, stdin=stdin, stdout=PIPE, stderr=PIPE) result = [x for x in proc.stdout.readlines()] result = ''.join(result); 当它是ASCII时,一切都正常。当我在stdout中接收UTF-8文本时,结果是不可预测的。在大多数情况下,输出损坏。这里怎么了 顺便说一句,也许应该以某种方式优化此代码?您是否尝试过解码字符
[...]
proc = Popen(path, stdin=stdin, stdout=PIPE, stderr=PIPE)
result = [x for x in proc.stdout.readlines()]
result = ''.join(result);
当它是ASCII时,一切都正常。当我在stdout
中接收UTF-8文本时,结果是不可预测的。在大多数情况下,输出损坏。这里怎么了
顺便说一句,也许应该以某种方式优化此代码?您是否尝试过解码字符串,然后将UTF-8字符串组合在一起?在Python2.4+(至少)中,这可以通过
result = [x.decode('utf8') for x in proc.stdout.readlines()]
重要的一点是,行
x
是必须解释为代表字符的字节序列。decode()
方法执行此解释(此处,字节假定为UTF-8编码):x.decode('utf8')
类型为unicode
,可以将其视为“字符串”(不同于“0到255[字节]之间的数字字符串”).我在使用时遇到了相同的问题
我通过为fdopen()指定额外的参数encoding='utf-8',errors='ignore'
解决了这个问题
您使用的是哪个版本的Python?2.x或3.x?@KennyTM我正在使用Python 2.4您是否尝试过
result=u'。加入(结果)
?@KennyTM现在我得到:UnicodeDecodeError:“ascii”编解码器无法解码第19位的字节0xe2:序号不在范围内(128)
“损坏”不是有用的信息。请提供(a)预期数据(b)损坏数据的简短示例。使用打印报告(xxxx\U数据)
并将输出复制/粘贴到问题的编辑版本中。@Vincenzo:谢谢。你是怎么做到的?通过编解码器模块?我只是按照你的建议更改了线路。“这很管用。”@Vincenzo:谢谢你提供的信息。我更新了答案,以反映它与Python2.4一起工作的事实:我不确定何时引入了.decode()
。
# https://codereview.stackexchange.com/questions/6567/redirecting-subprocesses-output-stdout-and-stderr-to-the-logging-module
class LogPipe(threading.Thread):
def __init__(self):
"""Setup the object with a logger and a loglevel
and start the thread
"""
threading.Thread.__init__(self)
self.daemon = False
# self.level = level
self.fdRead, self.fdWrite = os.pipe()
self.pipeReader = os.fdopen(self.fdRead, encoding='utf-8', errors='ignore') # set utf-8 encoding and just ignore illegal character
self.start()
def fileno(self):
"""Return the write file descriptor of the pipe
"""
return self.fdWrite
def run(self):
"""Run the thread, logging everything.
"""
for line in iter(self.pipeReader.readline, ''):
# vlogger.log(self.level, line.strip('\n'))
vlogger.debug(line.strip('\n'))
self.pipeReader.close()
def close(self):
"""Close the write end of the pipe.
"""
os.close(self.fdWrite)