unicode 在 Python 内部是如何表示的?

Posted

技术标签:

【中文标题】unicode 在 Python 内部是如何表示的?【英文标题】:How is unicode represented internally in Python? 【发布时间】:2014-11-22 15:15:07 【问题描述】:

Unicode 字符串在 Python 的内存中是如何按字面意思表示的?

例如,我可以将'abc' 可视化为它在内存中的等效 ASCII 字节。整数可以被认为是 2 的恭维表示。然而u'\u2049',即使在UTF-8 中表示为'\xe2\x81\x89' - 3 个字节长,我如何可视化内存中的文字u'\u2049' 代码点?

是否有特定的方式存储在内存中? Python 2 和 Python 3 对待它的方式不同吗?

对于任何好奇的人来说,很少有相关的问题:

1) How are these strings represented internally in Python interpreter ? I don't understand

2)What is internal representation of string in Python 3.x

【问题讨论】:

【参考方案1】:

我假设您想了解标准实现 CPython。 Python 2 和 Python 3.0-3.2 对 Unicode 字符使用 UCS2* 或 UCS4,这意味着 每个字符 将使用 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() 比包含的字符数长。

【讨论】:

要了解您是“窄” (UCS2) 还是“宽” (UCS4) 构建,请检查 sys.maxunicode。 65535 表示窄,1114111 表示宽。 我认为从技术上讲,它是 UTF-16 或 UTF-32,而不是 UCS2 或 UCS4,因为代理对用于窄构建,使其成为 UTF-16。 @NedBatchelder:确实,不知道为什么文档仍然坚持使用 UCS。 @NedBatchelder:但对于 Python 3,您可以再次将其称为 UCS2 和 UCS4,因为非 BMP 字符使用完整的 4 个字节表示。 @NedBatchelder:据我了解,UTF-32 只是 UCS4 的一个子集,因为不使用 Unicode 标准之外的字节;所以 4 字节的构建可以说是同时使用了 UTF-32 和 UCS4。

以上是关于unicode 在 Python 内部是如何表示的?的主要内容,如果未能解决你的问题,请参考以下文章

Python学习笔记

python 编码问题

python decode和encode

Python decode与encode

python字符串的encode和decode

Python中decode与encode的区别