Python 3中的Unicode字符串还依赖于“窄”/“宽”构建吗?
自从Python 2.2和PEP 261发布以来,Python可以以“窄模式”或“宽模式”构建,这会影响“字符”的定义,也就是“Python Unicode字符串中可以寻址的单位”。
在窄模式下构建的字符看起来像UTF-16代码单元:
>>> a = u'\N{MAHJONG TILE GREEN DRAGON}'
>>> a
u'\U0001f005'
>>> len(a)
2
>>> a[0], a[1]
(u'\ud83c', u'\udc05')
>>> [hex(ord(c)) for c in a.encode('utf-16be')]
['0xd8', '0x3c', '0xdc', '0x5']
(上面的内容似乎与一些 来源的说法相矛盾,这些来源坚持认为窄模式使用的是UCS-2,而不是UTF-16。确实很有趣)
Python 3.0还保持这种区分吗?还是说所有Python 3的构建都是宽模式的?
(我听说过PEP 393,它在3.3版本中改变了字符串的内部表示,但这与3.0到3.2版本无关。)
1 个回答
9
是的,从3.0版本到3.2版本,它们是有区别的。Windows系统使用的是窄字符集,而大多数Unix系统使用的是宽字符集。
在Windows上使用Python 3.2时:
>>> a = '\N{MAHJONG TILE GREEN DRAGON}'
>>> len(a)
2
>>> a
''
在Windows上,3.3版本及以上的行为是可以预期的:
>>> a = '\N{MAHJONG TILE GREEN DRAGON}'
>>> len(a)
1
>>> a
'\U0001f005'
>>> print(a)
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
print(a)
UnicodeEncodeError: 'UCS-2' codec can't encode character '\U0001f005'
in position 0: Non-BMP character not supported in Tk
在Tk中使用的是UCS-2编码(我在使用IDLE - 终端可能会显示其他错误)。