Python中的Unicode - 只是UTF-16?

时间:2012-10-26 22:55:30

标签: python unicode character-encoding utf-16

我很高兴在我的Python世界中知道当我需要向用户输出内容时,我正在用Unicode编码并编码为UTF-8。然后,我的一位同事用UTF-8发送了this article,这使我很困惑。

本文作者多次指出UCS-2,Python使用的Unicode表示与UTF-16同义。他甚至直接说Python使用UTF-16进行内部字符串表示。

作者还承认自己是Windows的爱好者和开发者,并指出MS多年来处理字符编码的方式导致了这个群体最困惑,所以也许只是他自己的混乱。我不知道......

有人可以解释一下Python中UTF-16与Unicode的状态是什么吗?它们是同义词,如果不是,它们是以什么方式存在的?

1 个答案:

答案 0 :(得分:19)

Python中Unicode字符串的内部表示形式(版本从2.2到3.2)取决于Python是以 wide 还是 narrow 模式编译的。大多数Python构建都很窄(您可以查看sys.maxunicode - 在窄版本上为65535,在宽版本上为1114111)。

对于宽版本,字符串是内部4字节宽字符的序列,即它们使用UTF-32编码。所有代码点的长度都是一个宽字符。

对于窄版本,字符串是使用UTF-16的内部2字节宽字符序列。使用通常的UTF-16代理对存储BMP以外的字符(代码点U + 10000及以上):

>>> q = u'\U00010000'
>>> len(q)
2
>>> q[0]
u'\ud800'
>>> q[1]
u'\udc00'
>>> q
u'\U00010000'

请注意,UTF-16和UCS-2不一样。 UCS-2是固定宽度编码:每个代码点编码为2个字节。因此,UCS-2 不能编码BMP之外的代码点。 UTF-16是可变宽度编码; BMP之外的代码点使用一对字符进行编码,称为代理对。


请注意,这一切都在3.3中进行了更改,并实现了PEP 393。现在,Unicode字符串使用足够宽的字符来表示,以容纳最大的代码点 - 对于ASCII字符串为8位,对于BMP字符串为16位,否则为32位。这消除了宽/窄分隔,并且当使用许多仅使用ASCII的字符串时,还有助于减少内存使用。