Python 中的 Unicode 和字符编码

2024年8月29日 | 阅读 8 分钟

本教程将向我们介绍字符编码和数字系统。我们将探索 Python 中字符串和字节如何使用编码,以及数字系统通过其各种形式的整型字面量。让我们先介绍一下 Python 中的字符编码。

什么是字符编码?

有许多字符编码,其中一种常见且简单的字符编码是 ASCII。您可能听说过 ASCII 表。ASCII 是开始学习字符编码的好方法,因为它是一种小型且包含的编码。它包括以下内容 -

  • 小写英文字母: az
  • 大写英文字母: AZ
  • 一些标点符号: "$" 和 "!",仅举几个例子
  • 空白字符: 实际的空格 (" "),以及换行符、回车符、水平制表符、垂直制表符以及其他一些字符
  • 一些不可打印字符: 诸如退格符 "\b" 之类的字符不能像字母 A 那样字面打印。

字符编码将字母、标点符号、符号、空格和控制字符转换为整数,并最终转换为二进制数字(位)。每个字符都映射到特定的位序列,从而允许以数字形式表示字符。如果您仍然不熟悉位的概念,请不要担心,我们将在稍后详细介绍它们。

列出的类别指的是 ASCII 表中划分为不同范围的字符组。ASCII 表中的每个字符都分配了一个代码点,可以将其视为一个整数值。

代码点范围Class
0 到 31控制/不可打印字符
32 到 64标点符号、符号、数字和空格
65 到 90大写英文字母
91 到 96额外的字素,例如 [ 和 \
97 到 122小写英文字母
123 到 126额外的字素,例如 { 和 |
127控制/不可打印字符 (DEL)

如上表所示,ASCII 表由 128 个字符组成。

字符串模块

Python 字符串模块是处理属于 ASCII 字符集的字符串常量的最佳工具。让我们看下面的例子。

示例 -

这些常量中的大多数都具有不言自明的标识符名称,这使得它们的用途清晰明了,无需额外的文档。

示例 -

输出

'Hello from JavaTpoint'

位的介绍

现在我们简单介绍一下位;它是计算机理解的最基本的信息单位。位是可以在两种可能状态之一中存在的信号。有各种符号表示,它们都具有相同的含义。

  • 0 或 1
  • "是" 或 "否"
  • True 或 False
  • "开" 或 "关"

这些十进制数也可以用二进制数字序列(基数 2)表示。以下是十进制数 0 到 10 的二进制等价物。

十进制二进制(紧凑)二进制(填充形式)
0000000000
1100000001
21000000010
31100000011
410000000100
510100000101
611000000110
711100000111
8100000001000
9100100001001
10101000001010

值得注意的是,随着十进制数的增加,需要更多的有效位来表示字符集,包括该数字。

在 Python 中,ASCII 字符串可以使用以下方便的方法表示为位序列。ASCII 字符串中的每个字符都表示为伪编码的 8 位序列,每个 8 位序列之间有空格,对应于单个字符。

输出

'01110011 01110100 01110010 01101001 01101110 01100111'
'01001010 01000001 01010110 01000001 01010100 01010000 01001111 01001001 01001110 01010100'
'00100100 00110010 00110011'

有一个关键公式与位的定义有关。对于给定数量的位 n,可以使用 n 位表示的唯一值的数量等于 2 的 n 次方。

示例 -

这意味着 -

  • 1 位将允许您表达 21 == 2 个可能值。
  • 8 位将允许您表达 28 == 256 个可能值。
  • 64 位将允许您表达 264 == 18,446,744,073,709,551,616 个可能值。

上述公式的一个结果允许我们完全确定表示一系列不同可能值所需的位数 n。为了计算 n,我们解方程 2 的 n 次方等于值范围 x,其中 x 已知。

示例 -

输出

8
5

n_bits_required() 方法中的天花板函数用于处理值范围不是 2 的幂次的情况。例如,考虑一个需要存储 26 个字符的字符集。乍一看,这将需要 log base 2 of 26(即 log(26) / log(2))位,大约 4.700 位。但是,由于位不能分成小数部分,26 个值将需要 5 位,最后一位槽位未使用。

由于 ASCII 只使用了现代计算机提供的 8 位字节的一小部分,因此出现了一系列非正式的编码方案,试图指定额外的字符以用于 8 位字符编码方案中剩余的 128 个代码点。不幸的是,这导致了一系列相互冲突且非标准化的编码。

什么是 Unicode?

正如我们了解 ASCII 及其存在的问题一样,它需要一个兼容的字符集来适应世界上的语言、方言、字形和符号。

Unicode 的工作原理与 ASCII 相同,但支持更大的代码点集。虽然在 ASCII 和 Unicode 标准之间按时间顺序出现了一些编码,但它们的用法随着时间的推移显着减少。这主要是因为 Unicode 及其编码方案,特别是 UTF-8,已成为计算行业中主要的编码标准。

Unicode 可以被视为一个大型 ASCII 表,拥有 1,114,112 个可能的代码点。ASCII 是 Unicode 的子集。然而,Unicode 通过添加额外的代码点来表示其他语言和脚本的字符,从而超越了 ASCII。

Unicode 不是一种编码,而是一种标准,它定义了一种一致的方式来表示各种脚本和语言中的字符和符号。

Unicode 将字符映射到唯一的代码点或整数,从而实现不同平台和系统之间的一致性。它是一个大型数据库表,将每个字符映射到唯一的代码点。

但是,为了在计算机内存或存储中表示这些代码点,它们必须以特定格式进行编码。这就是不同的字符编码发挥作用的地方。字符编码是一种以二进制形式表示 Unicode 代码点的特定方式,以便可以存储、传输和显示它们。

Unicode 包含全球各种脚本和语言中的大量字符和符号。它包括一套广泛的可打印和不可打印字符,涵盖各种符号、表情符号、数学符号等。

Unicode 与 UTF-8

所有字符不能打包成每个字节一个。由此可见,现代、更全面的编码需要使用多个字节来编码某些字符。

Unicode 标准定义了字符到唯一代码点或整数的映射,它还定义了几种不同的编码方案,用于以二进制形式表示这些代码点。这些编码方案具有不同的属性,例如可变长度字符,它们在存储空间、效率以及与不同系统和应用程序的兼容性方面提供了不同的权衡。

UTF-8,以及其较不常用的对应项 UTF-16 和 UTF-32,是字符编码格式,用于将 Unicode 字符表示为二进制数据,每个字符使用一个或多个字节。虽然我们将在稍后讨论 UTF-16 和 UTF-32,但值得注意的是,UTF-8 已成为最流行的编码格式,优势明显。

Python 中的编码和解码

Python 中的字符串类型表示人类可读的文本,可以包含 Unicode 字符。

另一方面,字节数据类型表示不包含编码的二进制数据。编码是将人类可读文本转换为字节的过程,解码是将字节数据转换为人类可读文本的过程。

Python 提供了 encode() 和 decode() 方法,默认以 'utf-8' 作为参数。

正如我们在上面的代码片段中看到的,encode() 方法将 résumé 转换为 b'r\xc3\xa9sum\xc3\xa9',并且字节表示只允许 ASCII 字符。

变长编码

变长编码是编码的关键特性。UTF-8 的独特之处在于一个 Unicode 字符可以使用一到四个字节表示。例如,考虑一个需要四个字节才能在 UTF-8 中表示的 Unicode 字符。

示例 -

需要注意 len() 的一个重要特性是单个 Unicode 字符作为 Python str 的长度与其使用 UTF-8 编码为字节时的长度之间的差异。

当一个 Unicode 字符表示为 Python str 时,无论它在内存中占用多少字节,其长度始终为 1。但是,当相同的字符使用 UTF-8 编码为字节时,其长度可以从 1 到 4 个字节,具体取决于编码的特定字符。

UTF-16 和 UTF-32

UTF-8 和 UTF-16 之间的区别很大。让我们看下面的例子。

如果您使用 UTF-8 编码四个希腊字母,然后使用 UTF-16 将生成的字节解码回文本,则文本可能会是完全不同的语言,例如韩语。

这强调了双向使用一致编码方案的重要性,因为对编码和解码使用不同的编码方案会导致严重错误的结果。相同字节对象的两种不同解码变体可以产生完全不同语言的文本,如果处理不当,可能会导致重大问题。

编码每字符字节数可变长度
UTF-81 到 4是的
UTF-162 到 4是的
UTF-324不能

另一个重要方面是 UTF-8 有时比 UTF-16 占用更少的空间。让我们理解以下示例。

示例 -

Python 提供了与数字系统和字符编码相关的内置方法。

  • ascii()
  • bin()
  • bytes()
  • chr()
  • hex()
  • int()
  • oct()
  • ord()
  • str()

结论

本教程详细介绍了编码和解码。编码和解码是现代计算中的基本过程,对于准确表示和传输数据至关重要。Unicode 是最常用的字符集,用于表示各种语言和脚本中的文本数据。为了存储和传输 Unicode 数据,使用不同的编码方案,例如 UTF-8、UTF-16 和 UTF-32,将 Unicode 代码点转换为二进制数据。因此,开发人员理解编码和解码过程并正确使用它们以确保数据完整性和准确性至关重要。