出于某种原因,从 UTF-8 文件中读取unicode字符串时,Python似乎遇到了 BOM 的问题。请考虑以下事项:
with open('test.py') as f:
for line in f:
print unicode(line, 'utf-8')
似乎很简单,不是吗?
这就是我的想法,直到我从命令行运行它并得到:
UnicodeEncodeError:'charmap'编解码器不能编码字符u'\ ufeff' 在位置0:字符映射到
<undefined>
对谷歌的简短访问显示,BOM必须手动清除:
import codecs
with open('test.py') as f:
for line in f:
print unicode(line.replace(codecs.BOM_UTF8, ''), 'utf-8')
这个运行正常。但是我很难看到这方面的任何优点。
上述行为背后是否存在理由?相比之下,UTF-16可以无缝运行。
答案 0 :(得分:28)
'utf-8-sig'
编码将代表您使用BOM签名。
答案 1 :(得分:13)
您写道:
UnicodeEncodeError: 'charmap' codec can't encode character u'\ufeff' in position 0: character maps to <undefined>
在Python中指定"utf-8"
编码时,它会引导您完成。 UTF-8文件不应该包含其中的BOM。它们既不是必需也不是推荐。对于8位代码单元,字节顺序没有意义。
BOM搞砸了,也是如此,因为你不能再做了:
$ cat a b c > abc
如果这些UTF-8文件中包含无关(读取:任何)BOM。现在看看为什么BOMs在UTF-8中如此愚蠢/糟糕/有害?他们实际上是在破坏事物。
BOM是元数据,而不是数据,UTF-8编码规范不像UTF-16和UTF-32规范那样允许它们。所以Python带你到你的话,遵循规范。很难为此负责。
如果您尝试使用BOM作为文件类型幻数来指定文件的内容,那么您真的不应该这样做。您应该使用更高级别的prototocl来实现这些元数据,就像使用MIME类型一样。
这只是另一个蹩脚的Windows错误,其解决方法是使用备用编码"utf-8-sig"
传递给Python。