使用 str() returns string with speech marks 将字节转换为字符串

Converting bytes to string with str() returns string with speech marks

假设我有一个包含字节的变量:

>>> a = b'Hello World'

可以通过以下方式验证:

>>> type(a)
<class 'bytes'>

现在我尝试使用 str():

将 a 转换为字符串
>>> b = str(a)

果然是一个字符串:

>>> type(b)
<class 'str'>

现在我尝试打印 b 但我得到了一个完全出乎意料的结果:

>>> print(b)
b'Hello World'

它 returns 是一个字符串,正如我所期望的那样,但它也保留了 b (字节符号)和 ' (引号)。

为什么要这样做,而不只是打印引号之间的消息?

不要将 bytes 值视为某些默认 8 位编码中的字符串。它只是二进制数据。因此,str(a) returns 一个 encoding-agnostic 字符串来表示字节字符串的值。如果你想要 'Hello World',请具体并解码值。

>>> b = a.decode()
>>> type(b)
>>> str
>>> print(b)
Hello World

在Python2 中,字节和文本之间的区别变得模糊。 Python 3 竭尽全力将两者分开:bytes 用于二进制数据,str 用于可读文本。

换个角度比较

>>> list("Hello")
['H', 'e', 'l', 'l', 'o']

>>> list(b"Hello")
[72, 101, 108, 108, 111]

str 通常将对象转换为表示它的字符串。没有比字节对象的 b'contains' 更好的表示了。您可能想使用 decode,其中您还指定字节对象的编码,在转换为字符串时应该使用

这里 str(b) 所做的是通过尝试调用 thing.__str__ 将字节转换为字符串,但失败了,因为字节没有 __str__,然后返回到 __repr__ ,其中 returns 在 repl.

中创建此对象所需的字符串

如果您考虑一下,仅仅将 bytes 转换为 str 意义不大,因为您需要知道编码。您可以使用 bytes.decode(encoding)bytes 正确转换为 str

b.decode("utf-8")

编码也可以留空,在这种情况下将选择默认值(可能是 utf-8)。

在 Python 3.x 中,当您使用 str(s) type-cast 字节字符串时,它会创建一个新字符串 b'Hello World' (保持 "b" 表示字节字符串在开头)。这是因为 byte-string 没有定义 __str__ 函数。因此,它调用 __repr__ 其中 returns 与用于表示其对象值的字节相同的字符串(即以 "b" 开头的字符串)。例如:

>>> a = b'Hello World'
>>> str(a)
"b'Hello World'"

有两种方法可以将byte-like对象转换为字符串。例如:

  1. 将byte-string解码为字符串:您可以decode将您的byte-stringa字符串为:

    >>> a.decode()
    'Hello World'
    
  2. 将byte-string转换为utf-8字符串为:

    >>> str(a, 'utf-8')
    'Hello World'