我有一个subprocess命令,它输出一些字符,比如'\xf1'。我试图将其解码为utf8,但我得到一个错误。
s = '\xf1'
s.decode('utf-8')
上述情况:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf1 in position 0: unexpected end of data
当我使用“拉丁语-1”时,它可以工作,但是utf8不也应该工作吗?我的理解是latin1是utf8的一个子集。
我是不是丢了什么东西?
编辑:
print s # ñ
repr(s) # returns "'\\xa9'"
你把Unicode和UTF-8混淆了。Latin-1是Unicode的子集,但它不是UTF-8的子集。避免像瘟疫一样考虑单个代码单元。只使用代码点。不要考虑UTF-8。想想Unicode吧。这就是你困惑的地方。
演示程序的源代码
在Python中使用Unicode非常简单。尤其是在Python 3和wide build s中,这是我使用Python的唯一方法,但是如果您在坚持使用UTF-8时非常小心,那么您仍然可以在狭窄的构建下使用遗留的Python 2。
为此,请始终将源代码编码和输出编码正确地转换为UTF-8。现在不要再想UTF了,在Python程序中只使用UTF-8文本、逻辑代码点编号或符号字符名。
这是带有行号的源代码:
下面是使用
\x{⋯}
符号的非ASCII字符uniquoted的打印函数:演示程序的示例运行
下面是该程序的一个运行示例,显示了三种不同的方式(a、b和c):第一种是在源代码中设置为文本(这将受到StackOverflow的NFC转换的限制,因此不可信任!!!)第二组是分别带有数字Unicode代码点和符号Unicode字符名的两组,同样是uniquoted,这样您就可以看到实际情况:
我真的不喜欢看二进制,但这里是二进制字节的样子:
故事的寓意
即使使用UTF-8源代码,也应该只考虑和使用逻辑Unicode代码点编号(或符号命名字符),而不是作为UTF-8(或UTF-16)序列表示的基础的单个8位代码单元。很少需要代码单元而不是代码点,这会让您感到困惑。
如果你使用Python3的广泛构建,你的行为也会比那些选择的替代方案更可靠,但这是UTF-32的问题,而不是UTF-8的问题。如果你只是顺其自然,UTF-32和UTF-8都很容易使用。
它是UTF-8中多字节序列的第一个字节,因此它本身是无效的。
实际上,它是4字节序列的第一个字节。
有关详细信息,请参见here。
UTF-8不是拉丁语-1的子集。UTF-8使用相同的单字节编码ASCII。对于所有其他代码点,都是多个字节。
简单地说,正如Python所说,xf1不是有效的UTF-8。”“意外的输入结束”表示此字节标记未提供的多字节序列的开始。
我建议你读一下UTF-8。
相关问题 更多 >
编程相关推荐