我将外部程序的标准输出捕获到一个字节对象中:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>>
>>> command_stdout
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

我想把它转换成一个普通的Python字符串,这样我就可以这样打印了:

>>> print(command_stdout)
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2

如何使用Python 3将字节对象转换为str?


当前回答

我想你真的想要这样:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')

Aaron的回答是正确的,只是你需要知道使用哪种编码。我相信Windows使用的是“Windows-1252”。只有当你的内容中有一些不寻常的(非ASCII)字符时,这才是重要的,但这会产生影响。

顺便说一句,这一点很重要,这是Python转而使用两种不同类型的二进制数据和文本数据的原因:它无法在它们之间进行神奇的转换,因为除非你告诉它,否则它不知道编码!您知道的唯一方法是阅读Windows文档(或在此处阅读)。

其他回答

这将字节列表合并为字符串:

>>> bytes_data = [112, 52, 52]
>>> "".join(map(chr, bytes_data))
'p44'

使用Windows系统中的数据(以行结尾)时,我的答案是

String = Bytes.decode("utf-8").replace("\r\n", "\n")

为什么?尝试使用多行Input.txt:

Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8")
open("Output.txt", "w").write(String)

所有的行尾都将加倍(到\r\n),导致多余的空行。Python的文本读取函数通常规范化行结尾,以便字符串只使用\n。如果您从Windows系统接收二进制数据,Python就没有机会这样做。因此

Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8").replace("\r\n", "\n")
open("Output.txt", "w").write(String)

将复制原始文件。

试试看:

bytes.fromhex('c3a9').decode('utf-8') 

我想你真的想要这样:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')

Aaron的回答是正确的,只是你需要知道使用哪种编码。我相信Windows使用的是“Windows-1252”。只有当你的内容中有一些不寻常的(非ASCII)字符时,这才是重要的,但这会产生影响。

顺便说一句,这一点很重要,这是Python转而使用两种不同类型的二进制数据和文本数据的原因:它无法在它们之间进行神奇的转换,因为除非你告诉它,否则它不知道编码!您知道的唯一方法是阅读Windows文档(或在此处阅读)。

在Python 3中,默认编码为“utf-8”,因此可以直接使用:

b'hello'.decode()

相当于

b'hello'.decode(encoding="utf-8")

另一方面,在Python 2中,编码默认为默认字符串编码。因此,您应该使用:

b'hello'.decode(encoding)

其中编码是所需的编码。

注意:Python 2.7中添加了对关键字参数的支持。