UnicodeEncodeError:'charmap'编解码器无法对位置0中的字符'\ x80'进行编码:字符映射到<undefined> </undefined>

时间:2013-12-18 11:17:19

标签: python unicode encoding

我有一个字符串,它由我的IDE(非常古老的Boa Constructor)自动转换为字节代码。 现在我想将它转换为unicode,以便在特定机器上打印它(在Windows上为cp1252或在Linux上为utf-8)。

我使用两种不同的方式。其中一个是工作,另一个是不工作。但为什么呢?

这是工作版本:

#!/usr/bin/python
# vim: set fileencoding=cp1252 :

str = '\x80'
str = str.decode('cp1252') # to unicode
str = str.encode('cp1252') # to str
print str

这里是不可用的版本:

#!/usr/bin/python
# vim: set fileencoding=cp1252 :

str = u'\x80'
#str = str.decode('cp1252') # to unicode
str = str.encode('cp1252') # to str
print str

在版本1中,我通过解码函数将str转换为unicode。 在版本2中,我通过字符串前面的u将str转换为unicode。 但我想,这两个版本会完全相同吗?

2 个答案:

答案 0 :(得分:1)

str.decode不只是将u添加到字符串文字中。它将输入字符串的字节转换为有意义的字符(即Unicode)。

然后您正在调用encode将此字符转换为字节,因为您需要“打印”,将它们输出到终端或任何其他OS实体(如GUI窗口)。

所以,关于你的具体任务,我相信你想要的东西:

s = '\x80'
print s.decode('cp1251').encode(platform_encoding)

其中'cp1251'是IDE的编码,platform_encoding是一个带有当前系统编码的变量。


在回复你的评论时:

  

但str.decode应该使用源代码编码(来自   文件中的第2行)进行解码。所以应该没有区别   你好

这是不正确的假设。来自Defining Python Source Code Encodings

  

然后Python解析器使用编码信息   使用给定的编码解释文件。

所以set fileencoding=cp1252只是告诉解释器在解析行str = '\x80'时如何将字符[通过编辑器输入]转换为字节。 str.decode来电期间不会使用此信息。

你也在问,''x80'是什么? \x80被简单地解释为\u0080,这显然不是您想要的。看看这个问题 - Bytes in a unicode Python string

答案 1 :(得分:1)

'\x80'.decode('cp1252')未提供u'\u0080'(与u'\x80'相同)。

Windows code page 1252中的字节0x80解码为Unicode字符 U + 20AC欧元符号。

有一种编码,其中所有字节0x00到0xFF都解码为具有相同数字U + 0000到U + 00FF的Unicode字符:它是iso-8859-1。使用该编码,您的示例可以正常工作。

Windows cp1252与该编码类似但不相同:虽然0xA0到0xFF与iso-8859-1中的相同,因此您获得这些字符的直接映射行为,字节0x80到0x9F是来自其他Unicode块的各种额外符号,而不是不可见(并且在很大程度上无用)的控制代码U + 0080到U + 009F。