Python中的ANSI、ASCII、Unicode和编码混淆
我之前很开心地在用BeautifulSoup,并且还用一个文本文件作为我Python脚本的输入参数。
然后我遇到了一个著名的“UnicodeEncodeError”错误。
我在Stack Overflow上看了很多相关的问题,但还是搞不清楚。
ASCII和这些有什么关系呢?我在文本编辑器(Notepad++)里应该用什么编码?ANSI还是UTF-8?
把字符串解码成ASCII似乎并不总是有效(我猜字符串是从BeautifulSoup来的,编码方式不同)。我该怎么解决这个问题呢?
总之,任何帮助和解释都非常感谢。
谢谢!
补充:我在看BeautifulSoup的文档时,它说只使用unicode,但我还是遇到了Unicode错误 :(
File "C:\Python26\lib\encodings\cp437.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u300d' in position
3: character maps to <undefined>
3 个回答
截至目前(2014年1月23日),关于Notepad++(记事本++)使用“ANSI”作为编码术语,似乎还有很多未解决的错误报告和讨论。
问题
在谷歌上搜索:notepad++ ansi encoding
结果:
Notepad++称之为“ANSI”的编码,大家知道在Ruby中该怎么称呼吗?
解决方案
以下的NPP论坛讨论似乎指向了对我来说最好的解决方案。
查看 编码检测,ANSI(Windows 1252)与UTF-8(无BOM)
偏好设置 -> 新文档 > 编码 > 选择“无BOM的UTF8”,然后应用到已打开的ANSI文件
我选择了上面的选项,而不是作者取消选择的。
然后我开始我的Python脚本,如下所示。
#!/usr/bin/python
# -*- coding: utf-8 -*-
ASCII和这些有什么关系呢?
Python没有办法知道文本是用什么编码存储的,所以默认假设是ASCII编码。不过,ASCII只定义了前128个字符,所以如果有字符超出了这个范围,就会出现解码错误(这其实是件好事,因为它不让你使用错误解码的字符串)。
大多数情况下,你的字符串会是UTF-8编码,因为这是最常用的Unicode编码方式,所以在处理str
类型的字符串时,通常可以安全地使用s.decode('utf-8')
(或者用unicode(s, 'utf-8')
)。
如果你事先不知道文本使用了什么编码,并且它没有提供编码的信息,你可以尝试使用chardet模块来检测。
BeautifulSoup可以以不同的编码和方式输出结果,所以你只需要指定你想要Unicode格式的输出。
ANSI并不是一种字符编码(在日常用语中,它通常指某些转义序列,但实际上它是美国国家标准协会的缩写)。你可以在Notepad++中设置编码(也可以检查你正在使用的编码)——希望你使用的是utf-8,因为这是一个通用的编码方式(可以表示任何Unicode字符)。你可以通过明确调用decode
方法,从utf-8编码的文本中构建Unicode,或者使用codecs.open
以Unicode格式读取文件(这两种方法都需要你指定编码名称——同样,希望是'utf8')。