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

>>> 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?


当前回答

对于“运行shell命令并将其输出作为文本而不是字节”的特定情况,在Python 3.7上,应该使用subprocess.run并传入text=True(以及capture_output=True来捕获输出)

command_result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
command_result.stdout  # is a `str` containing your program's stdout

文本过去被称为universal_newlines,在Python 3.7中被更改(嗯,别名)。如果希望支持3.7之前的Python版本,请传入universal_newlines=True而不是text=True

其他回答

解码字节字符串并将其转换为字符(Unicode)字符串。


Python 3:

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

or

str(b'hello', encoding)

Python 2:

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

or

unicode('hello', encoding)

虽然@Aaron Maenpaa的回答很有效,但一位用户最近问道:

还有什么更简单的方法吗?”fhand.read().decode(“ASCII”)'[…]太长了!

您可以使用:

command_stdout.decode()

decode()有一个标准参数:

codec.decode(obj,编码='utf-8',错误='strict')

我们可以使用bytes.decode(encoding='utf-8',errors='strict')对bytes对象进行解码以生成字符串。有关文档,请参阅bytes.decode。

Python 3示例:

byte_value = b"abcde"
print("Initial value = {}".format(byte_value))
print("Initial value type = {}".format(type(byte_value)))
string_value = byte_value.decode("utf-8")
# utf-8 is used here because it is a very common encoding, but you need to use the encoding your data is actually in.
print("------------")
print("Converted value = {}".format(string_value))
print("Converted value type = {}".format(type(string_value)))

输出:

Initial value = b'abcde'
Initial value type = <class 'bytes'>
------------
Converted value = abcde
Converted value type = <class 'str'>

注意:在Python 3中,默认情况下编码类型为UTF-8。因此,<byte_string>.decode(“utf-8”)也可以写成<byte-string>.decode()

将universal_newlines设置为True,即。

command_stdout = Popen(['ls', '-l'], stdout=PIPE, universal_newlines=True).communicate()[0]

尝试使用这个;此函数将忽略所有非字符集(如UTF-8)二进制文件,并返回一个干净的字符串。它针对Python 3.6及更高版本进行了测试。

def bin2str(text, encoding = 'utf-8'):
    """Converts a binary to Unicode string by removing all non Unicode char
    text: binary string to work on
    encoding: output encoding *utf-8"""

    return text.decode(encoding, 'ignore')

在这里,函数将获取二进制并对其进行解码(使用Python预定义的字符集将二进制数据转换为字符,忽略参数忽略二进制中的所有非字符集数据,并最终返回所需的字符串值)。

如果您不确定编码,请使用sys.getdefaultencoding()获取设备的默认编码。