在Python 2.7/3中,unicode( codecs.BOM_UTF8, "utf8" )是否必要?

6 投票
2 回答
2928 浏览
提问于 2025-04-17 06:07

在一次代码审查中,我遇到了以下代码:

# Python bug that renders the unicode identifier (0xEF 0xBB 0xBF)
# as a character.
# If untreated, it can prevent the page from validating or rendering 
# properly. 
bom = unicode( codecs.BOM_UTF8, "utf8" )
r = r.replace(bom, '')

这段代码是在一个函数里,这个函数把一个字符串传递给了响应对象(Django或Flask)。

在Python 2.7或3中,这个问题还算是个bug吗?我觉得可能不是,但我想问一下,因为我对这个问题不是很了解。

我不太确定这个问题是从哪里来的,但我在网上见过,有时和Jinja2(我们正在使用的模板引擎)一起提到。

谢谢你的阅读。

2 个回答

0

BOM是一串字节,用来说明使用了哪种Unicode编码。

BOM的作用是告诉解码器如何把这些字节转换成Unicode(因为Unicode可以有不同的二进制表示方式)。

把BOM放进一个Unicode字符串里是没有意义的。

7

根据Unicode标准,字符\ufeff有两种不同的含义。在数据流的开始部分,它应该用作字节顺序和/或编码的标识符,但在其他地方,它应该被理解为零宽非断行空格

所以这段代码

bom = unicode(codecs.BOM_UTF8, "utf8" )
r = r.replace(bom, '')

不仅仅是去掉了utf-8编码的标识符(也就是BOM),它还去掉了任何嵌入的零宽非断行空格

一些早期版本的Python没有一种可以在读取数据流时跳过BOM的“utf-8”编码方式。因为这和其他Unicode编码不一致,所以在2.5版本中引入了一种“utf-8-sig”编码方式,它可以跳过BOM。

所以代码注释中提到的“Python bug”可能和这个有关。

不过,更有可能的是这个“bug”与嵌入的\ufeff字符有关。但由于Unicode标准明确指出它们可以被视为合法字符,因此最终由数据的使用者决定如何处理它们——所以这并不是Python的一个bug。

撰写回答