您在评论中问道:“这让我感到疑惑。它是如何从原来的带口音变成现在这个样子的呢?当您说使用utf8和latin1进行双重编码时,这是3种编码(2种utf8 + 1种latin1)吗?从最初状态到当前状态的编码顺序是什么?”在Mark Byers的答案中,他说:“你似乎有一个被错误解码的UTF-8编码”。您接受了他的答案,但仍然感到困惑?好的,下面是详细描述:
注意:所有字符串都将使用(隐式)repr()显示。unicodedata.name()将用于验证内容。这样,控制台编码的变化就不会混淆字符串的解释。
初始状态:您有一个名为u1的Unicode对象。它包含了e-acute:
>>> u1 = u'\xe9'
>>> import unicodedata as ucd
>>> ucd.name(u1)
'LATIN SMALL LETTER E WITH ACUTE'
你需要将u1编码为UTF-8,并将结果命名为s:
>>> s = u1.encode('utf8')
>>> s
'\xc3\xa9'
您使用了错误的编码方式——latin1,应该使用utf8来解码s。否则得到的结果是无意义的垃圾。
>>> u2 = s.decode('latin1')
>>> u2
u'\xc3\xa9'
>>> ucd.name(u2[0]); ucd.name(u2[1])
'LATIN CAPITAL LETTER A WITH TILDE'
'COPYRIGHT SIGN'
>>>
请注意:当x!= y时,
unicode_object.encode('x').decode('y)
通常是无意义的;如果你幸运的话,它会引发异常;如果你不幸,它会悄悄地创建无意义的东西。同时,请理解,悄悄地创建无意义的东西并不是一个bug——Python(或任何其他语言)没有一般方法可以检测到已经犯了一个错误。这在涉及latin1时尤其适用,因为所有256个代码点都映射到前256个Unicode代码点中的1:1,所以从str_object.decode('latin1')中获取UnicodeDecodeError是不可能的。
当然,异常情况下(希望这是异常情况),您可能需要通过执行
gibberish_unicode_object.encode('y').decode('x')
来撤销这样的无意义操作,就像在回答您的问题时建议的那样。
u'Andr\xc3\xa9'
是通过utf8和latin1的双重编码得到的无意义字符串。千万不要这样做! - John Machin