在Windows上:
>>> a = u'\U0001f649'
>>> print a
>>> len(a)
2
>>> a[0]
u'\ud83d'
>>> a[1]
u'\ude49'
在linux上:
>>> a = u'\U0001f649'
>>> print a
>>> len(a)
1
>>> a[0]
u'\U0001f649'
那么为什么\U0001f649
会在Windows上转换为\ud83d
和\ude49
?有人可以彻底解释他们之间的整体关系/联系吗?另外,如何在Linux上将\U0001f649
转换为\ud83d
和\ude49
?
P.S。:两者都在Python 2.6.6上
Python 2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 bit (Intel)] on win32
Python 2.6.6 (r266:84292, Jan 22 2014, 09:42:36) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
答案 0 :(得分:4)
这是因为这两个版本使用不同的本机编码进行编译。 Windows版本在内部使用UTF-16,Linux版本在内部使用UCS-4 / UTF-32。
你可以看到差异:
在Windows和OSX上:
>>> import sys
>>> sys.maxunicode
65535
在Linux上,我认为你会得到1114112。
这意味着每个字符在Windows上占用2个字节,在Linux上占用4个字节。如果字符不适合,因为它高于65536,则以UTF-16编码。
对于您的问题,您可以通过以下方式查看两种不同的编码:
[UTF-16]
>>> a = u'\U0001f649'
>>> [hex(ord(x)) for x in a.encode('utf-16be')] # UTF-16, Big Endian
['0xd8', '0x3d', '0xde', '0x49']
对应于\ ud83d \ ude49,正如您在Windows上看到的那样。
[UTF-32]
>>> [hex(ord(x)) for x in a.encode('utf-32be')] # UTF-32, Big Endian
['0x0', '0x1', '0xf6', '0x49']
对应于\ U0001F649,正如您在Linux上看到的那样。
Wikipedia有一篇关于UTF-16的相当广泛的文章,但基本上,部分代码空间被搁置,并且每个单词中编码完整20位数的10位。
作为旁注,后续版本的Python 3完全取消了这一点。而不是每个字符串都是16位或32位,具体取决于编译时选项:每个字符串是8位,16位或32位,具体取决于字符串中的最大字符。这样效率要高得多,因为程序中的大多数字符串都是ASCII或仅基本多语言平面。