Python中Unicode字符串在内存中如何表示?
例如,我可以将'abc'
视为其在内存中等效的ASCII字节。整数可以认为是2的补码表示。然而,即使在UTF-8
中以'\xe2\x81\x89'
(3个字节)表示,u'\u2049'
的文字代码点在内存中该如何表示?
它是否有特定的存储方式?Python 2和Python 3是否有不同的处理方式?
其他几个相关问题:
Python中Unicode字符串在内存中如何表示?
例如,我可以将'abc'
视为其在内存中等效的ASCII字节。整数可以认为是2的补码表示。然而,即使在UTF-8
中以'\xe2\x81\x89'
(3个字节)表示,u'\u2049'
的文字代码点在内存中该如何表示?
它是否有特定的存储方式?Python 2和Python 3是否有不同的处理方式?
其他几个相关问题:
我假设您想了解CPython,即标准实现。Python 2和Python 3.0-3.2使用UCS2*或UCS4来表示Unicode字符,这意味着每个字符将使用2个或4个字节。选择哪个是编译时的选项。
\u2049
然后表示为 \x49\x20
或 \x20\x49
或 \x49\x20\x00\x00
或 \x00\x00\x20\x49
,取决于您系统的本地字节顺序以及是否选择了UCS2或UCS4。 Unicode字符串中的ASCII字符仍然每个字符占用2或4个字节。
Python 3.3切换到了新的内部表示形式,使用最紧凑的形式来表示字符串中的所有字符。会选择1个字节、2个字节或4个字节。 ASCII和Latin-1文本每个字符只使用1个字节,其余BMP字符需要2个字节,之后使用4个字节。
参见PEP-393:Flexible String Representation获取有关这些表示的完整信息。
* 严格来说,UCS-2构建使用UTF-16,因为非BMP字符使用UTF-16代理项将每个字符编码为4个字节(2个UTF-16字符)。但是,Python文档仍将其称为UCS2。
这会导致意外的行为,例如非BMP Unicode字符串上的 len()
比包含的字符数更长。
len()
函数不是计算字符串中Unicode码点的数量,而是计算字符串在内存中的编码长度吗? - undefinedlen()
函数返回该变量的值。然而,在旧版本的Python(不再受支持)中,使用UCS2编码时,如果存储了一个非BMP码点,那么它们将被计为两个字符而不是一个。例如,len(u"\U0001D49E")
(或len(u"\N{MATHEMATICAL SCRIPT CAPITAL C}")
)在这些版本中返回2
,因为在UCS2中,该码点由\ud835\udc9e
表示。 - undefined