Python 3中的Unicode字符串还依赖于“窄”/“宽”构建吗?

8 投票
1 回答
1492 浏览
提问于 2025-04-17 15:21

自从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 - 终端可能会显示其他错误)。

撰写回答