所以,我遇到了 Python3 编码问题。我有一些字节想用作字符串。 (长话短说)
简而言之,这很有效
a = "\x85".encode()
print(a.decode())
但这不是
b = (0x85).to_bytes(1,"big")
print(b.decode())
UnicodeDecodeError:utf-8 编解码器无法解码位置 0 中的字节 0x85: 无效起始字节
我读过一些关于这个主题的文章,但他们坚持认为“python3 已损坏”或“你不应该为此使用字符串”。 Stackoverflow 上的很多文章都只是使用“解决方法”(例如“出现错误时使用替换”或“用户 utc-16”)。
谁能告诉我区别在哪里以及为什么该功能有效而第二个功能无效?它们的工作方式不应该相同吗?为什么第二次尝试时 utf-8 无法解码该字节?
在第一种情况下,
'\x85'.encode()
以 Python 3 默认编码 UTF-8 编码 Unicode 代码点 U+0085。因此输出是该代码点的正确两字节 UTF-8 编码:
>>> '\x85'.encode()
b'\xc2\x85'
解码然后可以工作,因为它首先以 UTF-8 正确编码:
>>> b'\xc2\x85'.decode()
'\x85'
第二种情况是创建单字节字符串的复杂方法:
>>> (0x85).to_bytes(1,'big')
b'\x85'
该字节字符串未正确编码为 UTF-8,因此无法解码:
>>> b'\x85'.decode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x85 in position 0: invalid start byte
Python 3 绝对没有“损坏”。它将字节数据与文本清晰地分开。 如果您有原始字节,请将它们作为字节使用。 Python 3 中的原始数据旨在以字节字符串或字节数组的形式进行操作。 Unicode 字符串适用于文本。将字节解码为文本以对其进行操作,然后编码回字节以序列化到文件、套接字、数据库等。
如果出于某种原因您觉得需要对原始数据使用 Unicode 字符串,则 Unicode 的前 256 个代码点对应于
latin1
编解码器,用于一对一映射。
>>> '\x85'.encode('latin1')
b'\x85'
>>> b'\x85'.decode('latin1')
'\x85'
这通常用于纠正由于使用错误的编码进行编码/解码而导致的编程错误。