|
4 | 4 | "cell_type": "markdown",
|
5 | 5 | "metadata": {},
|
6 | 6 | "source": [
|
7 |
| - "# 字符串基础知识 \n", |
8 |
| - "## 字符编码方法 \n", |
| 7 | + "# 1. 字符串基础知识 \n", |
| 8 | + "## 1.1 字符编码方法 \n", |
9 | 9 | "大多数程序员把字符串看作是用来表示文本数据的一系列字符。但是,根据必须记录何种字符集,计算机内存中存储字符的方式有所不同。 \n",
|
10 | 10 | "\n",
|
11 | 11 | "ASCII 标准在美国创建,并且定义了大多数美国程序员使用的文本字符串表示法。ASCII 定义了从0到127的字符代码,并且允许每个字符存储在一个8位的字节中(实际上,只有其中的7位真正用到)。例如,ASCII 标准把字符 'a' 映射为整数值 97 (十六进制中的0x61),它存储在内存和文件的一个单个字节中:"
|
|
141 | 141 | "cell_type": "markdown",
|
142 | 142 | "metadata": {},
|
143 | 143 | "source": [
|
144 |
| - "## Python 如何在内存中存储字符串 \n", |
| 144 | + "## 1.2 Python 如何在内存中存储字符串 \n", |
145 | 145 | "前一节的编码实际上只适用于文本存储或传输到外部的文件和其他媒介中。在内存中,Python 总是以与编码无关的格式存储解码的文本字符串,对于每个字符,它可能使用或不使用多个字节。所有文本处理都以这种统一的内部格式进行。只有当被传输到或传输自外部文本文件、字节字符串或有特定编码需求的 API 时,文本才会被转换为特定的编码格式。然而,一旦在内存中,字符串就没有编码。它们只是本书中介绍的字符串对象。 \n",
|
146 | 146 | "\n",
|
147 | 147 | "Python 3.3 和更高版本使用的是可变长度方案,每个字符有 1、2 或 4 字节,具体取决于字符串的内容。大小是根据字符串中 Unicode 序号最大的字符来选择的。这种方案在通常情况下允许节省空间,但也允许在所有平台上使用完整的 UCS-4。 "
|
|
151 | 151 | "cell_type": "markdown",
|
152 | 152 | "metadata": {},
|
153 | 153 | "source": [
|
154 |
| - "## Python 字符串类型 \n", |
| 154 | + "## 1.3 Python 字符串类型 \n", |
155 | 155 | "Python 语言提供了字符串数据类型在脚本中表示字符文本。Python 3.X 带有 3 种字符串对象类型——一种用于文本数据,两种用于二进制数据:\n",
|
156 | 156 | "- `str` 表示 Unicode 文本(8位的和更宽的)。\n",
|
157 | 157 | "- `bytes` 表示二进制数据。\n",
|
|
173 | 173 | "cell_type": "markdown",
|
174 | 174 | "metadata": {},
|
175 | 175 | "source": [
|
176 |
| - "## 文本和二进制文件 \n", |
| 176 | + "## 1.4 文本和二进制文件 \n", |
177 | 177 | "文件 I/O(输入和输出)在 Python 3 中也有所改进,以反映 str/bytes 的区分以及对编码 Unicode 文本的自动支持。Python 现在在文本文件和二进制文件之间做了一个明显的独立于平台的区分:\n",
|
178 | 178 | "- 文本文件\n",
|
179 | 179 | " - 当一个文件以文本模式打开的时候,读取其数据会自动将其内容解码(每个平台一个默认的或一个提供的编码名称),并且将其返回为一个 `str` ,写入会接受一个 `str`,并且在将其传输到文件之前自动编码它。文本模式的文件还支持统一的行尾转换和额外的编码特定参数。根据编码名称,文本文件也自动处理文件开始处的字节顺序标记序列。\n",
|
|
189 | 189 | "cell_type": "markdown",
|
190 | 190 | "metadata": {},
|
191 | 191 | "source": [
|
192 |
| - "# Python 的字符串应用 \n", |
193 |
| - "## 字符串常量 \n", |
| 192 | + "# 2. Python 的字符串应用 \n", |
| 193 | + "## 2.1 字符串常量 \n", |
194 | 194 | "当调用 `str` 或 `bytes` 这样的一个内置函数、通过调用 `open` 创建读取一个文件或在脚本中编写常量语法时,会引发 Python 3 的字符串对象。对于后者,一种新的常量形式 `b'xxx'`(以及对等的 `B'xxx'`)用来创建 Python 3 中的 `bytes` 对象,`bytearray` 对象可以通过调用 `bytearray` 函数来创建,这会带有各种可能的参数。 \n",
|
195 | 195 | "\n",
|
196 | 196 | "在 Python 3 中,所有当前字符串常量形式,'xxx'、\"xxx\" 和三引号字符串块,都产生一个 `str`;在它们任何一种前面添加一个 `b` 或 `B` ,则会创建一个 `bytes`。这个新的 `b'...'` 字节常量类似于用来抑制反斜杠转义的 `r'...'` raw字符串。"
|
|
369 | 369 | "cell_type": "markdown",
|
370 | 370 | "metadata": {},
|
371 | 371 | "source": [
|
372 |
| - "## 字符串类型转换 \n", |
| 372 | + "## 2.2 字符串类型转换 \n", |
373 | 373 | "Python 3 中 `str` 和 `bytes` 类型对象不在表达式中自动地混合,并且当传递给函数的时候不会自动地相互转换。期待一个 `str` 对象作为参数的函数,通常不能接受一个 `bytes` ;反之亦然。 \n",
|
374 | 374 | "\n",
|
375 | 375 | "因此,Python 3 基本上要求遵守一种类型或另一种类型,或者手动执行显式转换:\n",
|
|
596 | 596 | "cell_type": "markdown",
|
597 | 597 | "metadata": {},
|
598 | 598 | "source": [
|
599 |
| - "# 编码 Unicode 字符串 \n", |
| 599 | + "# 3. 编码 Unicode 字符串 \n", |
600 | 600 | "要在字符串中编码任意的 Unicode 字符,有些字符可能甚至无法在键盘上输入,Python 的字符串常量支持 \"\\xNN\" 十六进制字节值转义以及 \"\\uNNNN\" 和 \"\\UNNNNNNNN\" Unicode 转义。 \n",
|
601 | 601 | "\n",
|
602 |
| - "## 编码 ASCII 文本 \n", |
| 602 | + "## 3.1 编码 ASCII 文本 \n", |
603 | 603 | "ASCII 文本是一种简单的 Unicode,存储为表示字符的字节值的一个序列:"
|
604 | 604 | ]
|
605 | 605 | },
|
|
668 | 668 | "cell_type": "markdown",
|
669 | 669 | "metadata": {},
|
670 | 670 | "source": [
|
671 |
| - "## 编码非 ASCII 文本 \n", |
| 671 | + "## 3.2 编码非 ASCII 文本 \n", |
672 | 672 | "要编码非 ASCII 字符,可能在字符串中使用十六进制或 Unicode 转义;十六进制转义限制于单个字节的值,但 Unicode 转义可以指定其值有两个和四个字节宽度的字符。也可以将其嵌入 Python 3 的 str 对象中:"
|
673 | 673 | ]
|
674 | 674 | },
|
|
779 | 779 | "cell_type": "markdown",
|
780 | 780 | "metadata": {},
|
781 | 781 | "source": [
|
782 |
| - "## 编码和解码非 ASCII 文本 \n", |
| 782 | + "## 3.3 编码和解码非 ASCII 文本 \n", |
783 | 783 | "如果我们试图把一个非 ASCII 字符串编码为 raw 字节以像 ASCII 一样使用,我们会得到一个错误,因为字符超出了 ASCII 的 7 位编码值范围:"
|
784 | 784 | ]
|
785 | 785 | },
|
|
925 | 925 | "cell_type": "markdown",
|
926 | 926 | "metadata": {},
|
927 | 927 | "source": [
|
928 |
| - "## 其他 Unicode 编码技术 \n", |
| 928 | + "## 3.4 其他 Unicode 编码技术 \n", |
929 | 929 | "一些编码甚至使用较大的字节序列来表示字符。当需要的时候,我们可以为自己字符串中的字符指定 16 位或 32 位的 Unicode 值,对于前者使用 `\"\\u...\"` 表示 4 个十六进制位,对于后者使用 `\"\\U....\"` 表示 8 个十六进制位。"
|
930 | 930 | ]
|
931 | 931 | },
|
|
994 | 994 | "cell_type": "markdown",
|
995 | 995 | "metadata": {},
|
996 | 996 | "source": [
|
997 |
| - "## 字节字符串常量:编码文本 \n", |
| 997 | + "## 3.5 字节字符串常量:编码文本 \n", |
998 | 998 | "这里有两点要注意。首先,Python 3 允许特殊的字符以十六进制和 Unicode 转义的方式编码到 `str` 字符串中,但是,只能以十六进制转义的方式编码到 `bytes` 字符串中:Unicode 转义会默默地逐字转换为字节常量,而不是转义。实际上,`bytes` 必须编码为 `str` 字符串,以便正常地打印非 ASCII 字符:"
|
999 | 999 | ]
|
1000 | 1000 | },
|
|
1252 | 1252 | "cell_type": "markdown",
|
1253 | 1253 | "metadata": {},
|
1254 | 1254 | "source": [
|
1255 |
| - "## 转换编码 \n", |
| 1255 | + "## 3.6 转换编码 \n", |
1256 | 1256 | "我们总是可以把一个字符串转换为不同于源字符集默认的一种编码,但是,我们必须显式地提供一个编码名称以进行编码和解码:"
|
1257 | 1257 | ]
|
1258 | 1258 | },
|
|
1350 | 1350 | "cell_type": "markdown",
|
1351 | 1351 | "metadata": {},
|
1352 | 1352 | "source": [
|
1353 |
| - "## 源文件字符集编码声明 \n", |
| 1353 | + "## 3.7 源文件字符集编码声明 \n", |
1354 | 1354 | "对于在脚本文件中编码的字符串,Python 默认地使用 UTF-8 编码,但是,它允许我们通过包含一个注释来指明想要的编码,从而将默认值修改为支持任意的字符集。这个注释必须拥有如下的形式,并且在 Python 中必须作为脚本的第一行或第二行出现:"
|
1355 | 1355 | ]
|
1356 | 1356 | },
|
|
1374 | 1374 | "cell_type": "markdown",
|
1375 | 1375 | "metadata": {},
|
1376 | 1376 | "source": [
|
1377 |
| - "# 使用 Python 3.X bytes 对象 \n", |
| 1377 | + "# 4. 使用 Python 3.X bytes 对象 \n", |
1378 | 1378 | "Python 3 bytes 对象是较小整数的一个序列,其中每个整数都在 0 到 255 之间,并且在显示的时候恰好打印为 ASCII 字符。 \n",
|
1379 | 1379 | "\n",
|
1380 |
| - "## 方法调用 \n", |
| 1380 | + "## 4.1 方法调用 \n", |
1381 | 1381 | "`bytes` 对象是不可改变的,就像是 Python 中的 `str` 对象一样:"
|
1382 | 1382 | ]
|
1383 | 1383 | },
|
|
1487 | 1487 | "cell_type": "markdown",
|
1488 | 1488 | "metadata": {},
|
1489 | 1489 | "source": [
|
1490 |
| - "## 序列操作 \n", |
| 1490 | + "## 4.2 序列操作 \n", |
1491 | 1491 | "如下的代码索引一个 `bytes` 对象并返回一个给出了该字节的二进制值的整数;`bytes` 实际上是 8 位整数的一个序列,但是,当作为整体显示的时候,为了方便起见,它打印为 ASCII 编码的字符的一个字符串。要查看一个给定的字节的值,使用 chr 内置函数来将其转换回字符:"
|
1492 | 1492 | ]
|
1493 | 1493 | },
|
|
1636 | 1636 | "cell_type": "markdown",
|
1637 | 1637 | "metadata": {},
|
1638 | 1638 | "source": [
|
1639 |
| - "## 创建 bytes 对象的其他方式 \n", |
| 1639 | + "## 4.3 创建 bytes 对象的其他方式 \n", |
1640 | 1640 | "可以用一个 `str` 和一个编码名来调用 `bytes` 构造函数,用一个可迭代的整数表示的字节值来调\n",
|
1641 | 1641 | "用 `bytes` 构造函数,或者按照每个默认(或传入的)编码来编码一个 `str` 对象,从而创建 `bytes` 对象:"
|
1642 | 1642 | ]
|
|
1770 | 1770 | "cell_type": "markdown",
|
1771 | 1771 | "metadata": {},
|
1772 | 1772 | "source": [
|
1773 |
| - "## 混合字符串类型 \n", |
| 1773 | + "## 4.4 混合字符串类型 \n", |
1774 | 1774 | "在 `replace` 调用中,我们必须传入两个 `bytes` 对象,`str` 对象在这里无效。Python 3 需要在某些环境下要求特殊的字符串类型并且如果需要的话期待手动转换:"
|
1775 | 1775 | ]
|
1776 | 1776 | },
|
|
1943 | 1943 | "cell_type": "markdown",
|
1944 | 1944 | "metadata": {},
|
1945 | 1945 | "source": [
|
1946 |
| - "# 使用 Python 3.X bytearray 对象 \n", |
| 1946 | + "# 5. 使用 Python 3.X bytearray 对象 \n", |
1947 | 1947 | "Python 3 还有第三个字符串类型 `bytearray`,这是范围在 0 到 255 之间的整数的一个可变的序列,其本质是 `bytes` 的可变的变体。 \n",
|
1948 | 1948 | "\n",
|
1949 |
| - "## bytearray 应用 \n", |
| 1949 | + "## 5.1 bytearray 应用 \n", |
1950 | 1950 | "`bytearray` 需要一个编码名称和字节字符串,因为文本和二进制字符串不能混合:"
|
1951 | 1951 | ]
|
1952 | 1952 | },
|
|
2282 | 2282 | "cell_type": "markdown",
|
2283 | 2283 | "metadata": {},
|
2284 | 2284 | "source": [
|
2285 |
| - "## Python 3.X 字符串类型总结 \n", |
| 2285 | + "## 5.2 Python 3.X 字符串类型总结 \n", |
2286 | 2286 | "下面的例子展示了 `bytes` 和 `bytearray` 对象如何是 `int` 的序列,而 `str` 对象是字符的序列:"
|
2287 | 2287 | ]
|
2288 | 2288 | },
|
|
2381 | 2381 | "cell_type": "markdown",
|
2382 | 2382 | "metadata": {},
|
2383 | 2383 | "source": [
|
2384 |
| - "# 使用文本文件和二进制文件 \n", |
| 2384 | + "# 6. 使用文本文件和二进制文件 \n", |
2385 | 2385 | "- 文本模式文件 根据 Unicode 编码来解释文件内容,要么是平台的默认编码,要么是我们传递进的编码名。通过传递一个编码名来打开文件,我们可以强行进行 Unicode 文件的各种类型的转换。文本模型的文件也执行通用的行末转换:默认地,所有的行末形式映射为脚本中的一个单个的 '\\n' 字符,而不管在什么平台上运行。文本文件也负责阅读和写入在某些 Unicode 编码方案中存储文件开始处的**字节顺序标记**(Byte Order Mark,BOM)。\n",
|
2386 | 2386 | "- 二进制模式文件 不会返回**原始的**文件内容,而是作为表示字节值的整数的一个序列,没有编码或解码,也没有行末转换。\n",
|
2387 | 2387 | "\n",
|
2388 |
| - "## Python 3.X 中的文本和二进制模式 " |
| 2388 | + "## 6.1 Python 3.X 中的文本和二进制模式 " |
2389 | 2389 | ]
|
2390 | 2390 | },
|
2391 | 2391 | {
|
|
2529 | 2529 | "cell_type": "markdown",
|
2530 | 2530 | "metadata": {},
|
2531 | 2531 | "source": [
|
2532 |
| - "## 类型和内容错误匹配 \n", |
| 2532 | + "## 6.2 类型和内容错误匹配 \n", |
2533 | 2533 | "如果试图向一个文本文件写入一个 `bytes` 或者向二进制文件写入一个 `str` ,将会得到错误:"
|
2534 | 2534 | ]
|
2535 | 2535 | },
|
|
2626 | 2626 | "cell_type": "markdown",
|
2627 | 2627 | "metadata": {},
|
2628 | 2628 | "source": [
|
2629 |
| - "# 使用 Unicode 文件 \n", |
| 2629 | + "# 7. 使用 Unicode 文件 \n", |
2630 | 2630 | "Python 3 的 `open` 调用针对文本文件接受一个编码,在数据传输的时候,它自动为我们编码和解码。这允许我们处理用不同编码创建的 Unicode 文本,而不仅是平台默认编码的 Unicode 文本,并且以不同的编码存储以供转换。 \n",
|
2631 | 2631 | "\n",
|
2632 |
| - "## 在 Python 3.X 中读取和写入 Unicode \n", |
| 2632 | + "## 7.1 在 Python 3.X 中读取和写入 Unicode \n", |
2633 | 2633 | "有两种办法可以把字符串转换为不同的编码:用方法调用手动地转换和在文件输入输出上自动地转换。"
|
2634 | 2634 | ]
|
2635 | 2635 | },
|
|
2885 | 2885 | "cell_type": "markdown",
|
2886 | 2886 | "metadata": {},
|
2887 | 2887 | "source": [
|
2888 |
| - "## Unicode 文件名和流 \n", |
| 2888 | + "## 7.2 Unicode 文件名和流 \n", |
2889 | 2889 | "Python 也支持非 ASCII 文件名的概念。它们在 sys 中是独立的设置,每个 Python 版本和平台都可能不同:"
|
2890 | 2890 | ]
|
2891 | 2891 | },
|
|
2973 | 2973 | "name": "python",
|
2974 | 2974 | "nbconvert_exporter": "python",
|
2975 | 2975 | "pygments_lexer": "ipython3",
|
2976 |
| - "version": "3.6.6" |
| 2976 | + "version": "3.6.8" |
2977 | 2977 | }
|
2978 | 2978 | },
|
2979 | 2979 | "nbformat": 4,
|
|
0 commit comments