1、第 八 部 分 高 级 话 题893 第36 章 Unicode 和 字 节 字 符 串 在 本 书 的 核 心 类 型 部 分 关 于 字 符 串 的 一 章 中 ( 第7 章 ) , 我 有 意 地 限 制 了 大 多 数Python 程 序 员 需 要 了 解 的 字 符 串 话 题 的 子 集 的 范 围 。 因 为 大 多 数 程 序 员 只 是 处 理 像ASCII 这 样 的 文 本 的 简 单 形 式 , 他 们 快 乐 地 使 用 着Python 的 基 本 的str 字 符 串 类 型 及 其 相 关 的 操 作 , 并 且 不 需 要 掌 握 更 加 高 级 的 字 符
2、串 概 念 。 实 际 上 , 这 样 的 程 序 员 很 大 程 度 上 可 以 忽 略 Python 3.0 中 的 字 符 串 的 变 化 , 并 且 继 续 使 用 他 们 过 去 所 使 用 的 字 符 串 。 另 一 方 面 , 一 些 程 序 员 处 理 更 加 专 业 的 数 据 类 型 : 非A S C I I 的 字 符 串 集 、 图 像 文 件 内 容 , 等 等 。 对 于 这 些 程 序 员 ( 以 及 其 他 可 能 某 一 天 加 入 这 一 队 伍 的 程 序 员 ) , 在 本 章 中 , 我 们 将 介 绍Python 字 符 串 的 其 他 内 容 ,
3、并 且 探 讨Python 字 符 串 模 型 中 一 些 较 为 高 级 的 话 题 。 特 别 是 , 我 们 将 介 绍Python 支 持 的Unicode 文 本 的 基 础 知 识 在 国 际 化 应 用 程 序 中 使 用 的 宽 字 符 字 符 串 , 以 及 二 进 制 数 据 表 示 绝 对 的 字 节 值 的 字 符 串 。 我 们 将 看 到 , 高 级 的 字 符 串 表 示 法 在Python 当 前 版 本 中 已 经 产 生 了 分 歧 : Python 3.0 为 二 进 制 数 据 提 供 了 一 种 替 代 字 符 串 类 型 , 并 且 在 其 常 规
4、的 字 符 串 类 型 中 支 持Unicode 文 本 (ASCII 看 作Unicode 的 一 种 简 单 类 型 ) 。 Python 2.6 为 非ASCII Unicode 文 本 提 供 了 一 种 替 代 字 符 串 类 型 , 并 且 在 其 常 规 的 字 符 串 类 型 中 支 持 简 单 文 本 和 二 进 制 数 据 。 此 外 , 由 于Python 的 字 符 串 模 式 对 于 如 何 处 理 非ASCII 文 件 有 着 直 接 的 影 响 , 我 们 还 将 在 这 里 介 绍 相 关 话 题 的 基 础 知 识 。 最 后 , 我 们 还 将 简 单 地
5、看 看 一 些 高 级 字 符 串 和 二 进 制 工 具 , 例 如 模 式 匹 配 、 对 象pickle 化 、 二 进 制 数 据 包 装 和XML 解 析 , 以 及Python 3.0 的 字 符 串 变 化 对 它 们 产 生 影 响 的 方 式 。 894 第36 章 正 式 来 说 , 本 章 是 关 于 高 级 话 题 的 一 章 , 因 为 并 不 是 所 有 的 程 序 员 都 需 要 深 入Unicode 编 码 或 二 进 制 数 据 的 世 界 。 如 果 你 需 要 关 注 处 理 这 两 种 形 式 , 那 么 , 你 将 会 发 现Python 的 字 符
6、串 模 式 提 供 了 所 需 的 支 持 。 Python 3.0 中 的 字 符 串 修 改 Python 3.0 中 最 引 入 注 目 的 修 改 之 一 , 就 是 字 符 串 对 象 类 型 的 变 化 。 简 而 言 之 ,Python 2.X 的str 和unicode 类 型 已 经 融 入 了Python 3.0 的str 和bytes 类 型 , 并 且 增 加 了 一 种 新 的 可 变 的 类 型bytearray 。bytearray 类 型 在Python 2.6 中 也 可 以 使 用 ( 但 在 更 早 的 版 本 中 不 能 用 ) , 但 是 , 它 在P
7、ython 3.0 中 得 到 完 全 支 持 , 并 且 不 像 是Python 2.6 中 那 样 清 楚 地 区 分 文 本 和 二 进 制 内 容 。 特 别 是 , 如 果 我 们 处 理 本 质 上 是Unicode 或 二 进 制 的 数 据 , 这 些 修 改 对 于 代 码 可 能 会 有 切 实 的 影 响 。 实 际 上 , 作 为 首 要 的 一 般 性 规 则 , 我 们 需 要 如 何 关 注 这 一 话 题 , 很 大 程 度 上 取 决 于 遇 到 如 下 的 哪 种 情 况 : 如 果 处 理 非ASCII Unicode 文 本 , 例 如 , 在 国 际
8、化 应 用 程 序 或 某 些XML 解 析 器 的 结 果 这 样 的 环 境 中 , 你 将 会 发 现Python 3.0 中 对 文 本 编 码 的 支 持 是 不 同 的 , 但 是 可 能 比Python 2.6 中 的 支 持 更 加 直 接 、 易 用 和 无 缝 。 如 果 处 理 二 进 制 数 据 , 例 如 , 使 用struct 模 块 处 理 的 图 形 或 音 频 文 件 的 形 式 或 打 包 的 数 据 , 我 们 需 要 理 解Python 3.0 中 新 的bytes 对 象 , 以 及Python 3.0 对 文 本 和 二 进 制 数 据 和 文 件
9、的 不 同 和 严 格 区 分 。 如 果 不 属 于 前 面 两 种 情 况 的 任 何 一 种 , 在Python 3.0 中 , 通 常 可 以 像 是 在Python 2.6 中 一 样 使 用 字 符 串 : 使 用 通 用 的s t r 字 符 串 类 型 、 文 本 文 件 , 以 及 我 们 前 面 所 介 绍 的 所 有 熟 悉 的 字 符 串 操 作 。 字 符 串 将 使 用 平 台 默 认 的 编 码 来 进 行 编 码 和 解 码 ( 例 如 , 美 国 的Windows 上 的ASCII 或UTF-8 , 如 果 我 们 仔 细 检 查 的 话 ,sys. getd
10、efaultencoding() 给 出 默 认 的 编 码 方 式 ) , 但 是 , 你 可 能 不 会 注 意 。 换 句 话 说 , 如 果 你 的 文 本 总 是ASCII , 可 以 使 用 常 规 的 字 符 串 对 象 和 文 本 文 件 , 并 且 避 免 下 面 介 绍 的 大 多 数 情 况 。 正 如 稍 后 我 们 将 见 到 的 ,ASCII 是 一 种 简 单 的Unicode , 并 且 是 其 他 编 码 的 一 个 子 集 , 因 此 , 如 果 你 的 程 序 处 理ASCII 文 本 , 字 符 串 操 作 和 文 件 “ 刚 好 够 用 ” 。 即 便
11、 你 遇 到 了 刚 刚 提 及 的3 种 情 况 的 最 后 一 种 , 然 而 对Python 3.0 字 符 串 模 式 的 基 本 理 解 , 既 可 以 帮 助 你 理 解 一 些 底 层 的 行 为 , 也 可 以 帮 助 你 更 容 易 地 掌 握Unicode 或 二 进 制 数 据 问 题 , 以 免 它 们 将 来 会 影 响 到 你 。 Unicode 和字节字符串 895 Python 3.0 对Unicode 和 二 进 制 数 据 的 支 持 在Python 2.6 中 也 可 以 使 用 , 虽 然 形 式 不 同 。 尽 管 本 章 中 主 要 关 注 的 是P
12、ython 3.0 中 的 字 符 串 类 型 , 在 此 过 程 中 , 我 们 还 将 讨 论 一 些 Python 2.6 中 的 不 同 之 处 。 不 管 你 使 用 的 是 哪 个 版 本 , 我 们 在 这 里 介 绍 的 工 具 在 很 多 类 型 程 序 中 将 变 得 重 要 起 来 。 字 符 串 基 础 知 识 在 查 看 任 何 代 码 之 前 , 让 我 们 先 开 始 概 览 一 下P y t h o n 的 字 符 串 模 型 。 要 理 解 为 什 么 Python 3.0 改 变 了 字 符 串 的 工 作 方 式 , 我 们 必 须 先 简 短 地 看 看
13、 字 符 实 际 是 如 何 在 计 算 机 中 表 示 的 。 字 符 编 码 方 法 大 多 数 程 序 员 把 字 符 串 看 作 是 用 来 表 示 文 本 数 据 的 一 系 列 字 符 。 但 是 , 根 据 必 须 记 录 何 种 字 符 集 , 计 算 机 内 存 中 存 储 字 符 的 方 式 有 所 不 同 。 ASCII 标 准 在 美 国 创 建 , 并 且 定 义 了 大 多 数 美 国 程 序 员 使 用 的 文 本 字 符 串 表 示 法 。ASCII 定 义 了 从0 到127 的 字 符 代 码 , 并 且 允 许 每 个 字 符 存 储 在 一 个8 位 的
14、 字 节 中 ( 实 际 上 , 只 有 其 中 的7 位 真 正 用 到 ) 。 例 如 ,A S C I I 标 准 把 字 符a 映 射 为 整 数 值97 ( 十 六 进 制 中 的0x61 ) , 它 存 储 在 内 存 和 文 件 的 一 个 单 个 字 节 中 。 如 果 想 要 看 到 这 是 如 何 工 作 的 , Python 的 内 置 函 数ord 给 出 了 一 个 字 符 的 二 进 制 值 , 并 且chr 针 对 一 个 给 定 的 整 数 代 码 值 返 回 其 字 符 : ord(a) # a is a byte with binary value 97 i
15、n ASCII 97 hex(97) 0x61 chr(97) # Binary value 97 stands for character a a 然 而 , 有 时 候 每 个 字 符 一 个 字 节 并 不 够 。 例 如 , 各 种 符 号 和 重 音 字 符 并 不 在ASCII 所 定 义 的 可 能 字 符 的 范 围 中 。 为 了 容 纳 特 殊 字 符 , 一 些 标 准 允 许 一 个8 位 字 节 中 的 所 有 可 能 的 值 ( 即0 到255 ) 来 表 示 字 符 , 并 且 把 (ASCII 范 围 之 外 的 ) 值128 到255 分 配 给 特 殊 字
16、符 。 这 样 的 一 个 标 准 叫 做Latin-1 , 广 泛 地 用 于 西 欧 地 区 。 在Latin-1 中 ,127 以 上 的 字 符 代 码 分 配 给 了 重 音 和 其 他 特 殊 字 符 。 例 如 , 分 配 给 字 节 值196 的 字 符 , 是 一 个 特 殊 标 记 的 非ASCII 字 符 : 0xC4 196 chr(196) 896 第36 章 这 个 标 准 考 虑 到 范 围 较 广 的 额 外 特 殊 字 符 。 然 而 , 一 些 字 母 表 定 义 了 如 此 多 的 字 符 , 以 至 于 无 法 把 其 中 的 每 一 个 都 表 示 成
17、 一 个 字 节 。Unicode 考 虑 到 更 多 的 灵 活 性 。Unicode 文 本 通 常 叫 做 “ 宽 字 符 ” 字 符 串 , 因 为 每 个 字 符 可 能 表 示 为 多 个 字 节 。Unicode 通 常 用 在 国 际 化 的 程 序 中 , 以 表 示 欧 洲 和 亚 洲 的 字 符 集 , 它 们 往 往 拥 有 比8 位 字 节 所 能 表 示 的 更 多 的 字 符 。 要 在 计 算 机 内 存 中 存 储 如 此 丰 富 的 文 本 , 我 们 要 确 保 字 符 与 原 始 字 节 之 间 可 以 使 用 一 种 编 码 相 互 转 换 , 而 编
18、 码 就 是 把 一 个Unicode 字 符 转 换 为 字 节 序 列 以 及 从 一 个 字 节 序 列 提 取 字 符 串 的 规 则 。 更 程 序 化 地 说 , 字 节 和 字 符 串 之 间 的 来 回 转 换 由 两 个 术 语 定 义 : 编 码 是 根 据 一 个 想 要 的 编 码 名 称 , 把 一 个 字 符 串 翻 译 为 其 原 始 字 节 形 式 。 解 码 是 根 据 其 编 码 名 称 , 把 一 个 原 始 字 节 串 翻 译 为 字 符 串 形 式 的 过 程 。 也 就 是 说 , 我 们 从 字 符 串 编 码 为 原 始 字 节 , 并 且 从
19、原 始 字 节 解 码 为 字 符 串 。 对 于 某 些 编 码 , 翻 译 的 过 程 很 简 单 , 例 如ASCII 和Latin-1 , 把 每 个 字 符 映 射 为 一 个 单 个 字 节 , 因 此 , 不 需 要 翻 译 工 作 。 对 于 其 他 的 编 码 , 映 射 可 能 更 复 杂 些 , 并 且 每 个 字 符 产 生 多 个 字 节 。 例 如 , 广 为 使 用 的UTF-8 编 码 , 通 过 采 用 可 变 的 字 节 数 的 方 案 , 允 许 表 示 众 多 的 字 符 。 小 于128 的 字 符 代 码 表 示 为 单 个 字 节 ;128 和0x
20、7ff (2047) 之 间 的 代 码 转 换 为 两 个 字 节 , 而 每 个 字 节 拥 有 一 个128 到255 之 间 的 值 ;0x7ff 以 上 的 代 码 转 换 为3 个 或4 个 字 节 序 列 , 序 列 中 的 每 个 字 节 的 值 在128 到255 之 间 。 这 保 持 了ASCII 字 符 串 的 紧 凑 , 避 免 了 字 节 排 序 问 题 , 并 且 避 免 了 可 能 对C 库 和 网 络 连 接 引 发 问 题 的 空 ( 零 ) 字 节 。 由 于 编 码 的 字 符 映 射 把 字 符 分 配 给 同 样 的 代 码 以 保 持 兼 容 性
21、, 因 此ASCII 是Latin-1 和 UTF-8 的 子 集 。 也 就 是 说 , 一 个 有 效 的ASCII 字 符 串 也 是 一 个 有 效 的Latin-1 和UTF-8 编 码 字 符 串 。 当 数 据 存 储 到 文 件 中 的 时 候 , 这 也 是 成 立 的 : 每 个ASCII 文 件 也 是 有 效 的UTF-8 文 件 , 因 为ASCII 是UTF-8 的 一 个7 位 的 子 集 。 反 过 来 , 对 于 所 有 小 于128 的 字 符 代 码 ,UTF-8 编 码 与ASCII 是 二 进 制 兼 容 的 。Latin-1 和UTF-8 只 不 过
22、 是 考 虑 到 了 额 外 的 字 符 :Latin-1 是 为 了 在 一 个 字 节 内 映 射 为128 到255 的 值 ,UTF-8 是 考 虑 到 可 能 用 多 个 字 节 表 示 的 字 符 串 。 其 他 的 编 码 以 类 似 的 方 式 允 许 较 宽 的 字 符 集 合 , 但 是 , 所 有 这 些 ,ASCII 、Latin-1 、UTF-8 以 及 很 多 其 他 的 编 码 , 都 被 认 为 是Unicode 。 对 于Python 程 序 员 来 说 , 编 码 指 定 为 包 含 了 编 码 名 的 字 符 串 。Python 带 有 大 约100 种
23、不 同 的 编 码 , 参 见Python 库 参 考 可 以 找 到 一 个 完 整 的 列 表 。 导 入encodings 模 块 并 运 行 help(encodings) 也 会 显 示 很 多 的 编 码 名 称 , 一 些 是 在Python 中 实 现 的 , 一 些 是 在C 中 实 现 的 。 一 些 编 码 也 有 多 个 名 称 , 例 如 ,latin-1 、iso_8859_1 和8859 都 是 相 同 编 码 的 名 Unicode 和字节字符串 897 称 , 即Latin-1 。 我 们 将 会 在 本 章 稍 后 学 习 在 脚 本 中 编 写Unicod
24、e 字 符 串 技 术 的 时 候 , 再 次 介 绍 编 码 。 要 了 解 关 于Unicode 的 更 多 内 容 , 参 见Python 标 准 手 册 集 。 它 在 “Python HOWTOs ” 部 分 包 括 了 一 个 “Unicode HOWTO ” , 其 中 提 供 了 额 外 的 背 景 知 识 , 考 虑 到 篇 幅 的 问 题 , 我 们 暂 时 在 此 省 略 。 Python 的 字 符 串 类 型 具 体 来 说 ,Python 语 言 提 供 了 字 符 串 类 型 在 脚 本 中 表 示 字 符 文 本 。 在 脚 本 中 所 使 用 的 字 符 串
25、类 型 取 决 于 所 使 用 的Python 的 版 本 。Python 2.X 有 一 种 通 用 的 字 符 串 类 型 来 表 示 二 进 制 数 据 和 像ASCII 这 样 的8 位 文 本 , 还 有 一 种 特 定 的 类 型 用 来 表 示 多 字 节Unicode 文 本 : str 表 示8 位 文 本 和 二 进 制 数 据 。 unicode 用 来 表 示 宽 字 符Unicode 文 本 。 Python 2.X 的 两 种 字 符 串 类 型 是 不 同 的 (unicode 考 虑 到 字 符 的 额 外 大 小 并 且 支 持 编 码 和 解 码 ) , 但
26、 是 , 它 们 的 操 作 集 大 多 是 重 叠 的 。Python 2.X 中 的str 字 符 串 类 型 用 于 可 以 用8 位 字 节 表 示 的 文 本 , 以 及 绝 对 字 节 值 所 表 示 的 二 进 制 数 据 。 相 反 ,Python 3.X 带 有3 种 字 符 串 对 象 类 型 一 种 用 于 文 本 数 据 , 两 种 用 于 二 进 制 数 据 : str 表 示Unicode 文 本 (8 位 的 和 更 宽 的 ) 。 bytes 表 示 二 进 制 数 据 。 bytearray , 是 一 种 可 变 的bytes 类 型 。 正 如 前 面 所
27、 提 到 的 ,bytearray 在Python 2.6 中 可 以 使 用 , 但 它 是 从Python 3.0 才 有 的 升 级 功 能 , 此 后 较 少 有 特 定 内 容 的 行 为 , 并 且 通 常 看 做 是 一 个Python 3.0 类 型 。 Python 3.0 中 所 有3 种 字 符 串 类 型 都 支 持 类 似 的 操 作 集 , 但 是 , 它 们 都 有 不 同 的 角 色 。 Python 3.X 之 后 关 于 这 一 修 改 的 主 要 目 标 是 , 把Python 2.X 中 常 规 的 和Unicode 字 符 串 类 型 合 并 到 一
28、个 单 独 的 字 符 串 类 型 中 , 以 支 持 常 规 的 和Unicode 文 本 : 开 发 者 想 要 删 除 Python 2.X 中 的 字 符 串 区 分 , 并 且 让Unicode 的 处 理 更 加 自 然 。 假 设ASCII 和 其 他 的8 位 文 本 真 的 是 一 种 简 单 的Unicode , 这 种 融 合 听 起 来 很 符 合 逻 辑 。 为 了 实 现 这 一 点 ,Python 3.0 的str 类 型 定 义 为 一 个 不 可 改 变 的 字 符 序 列 ( 不 一 定 是 字 节 ) , 这 可 能 是 像ASCII 这 样 的 每 个
29、字 符 一 个 字 节 的 常 规 文 本 , 或 者 是 像UTF-8 Unicode 这 样 可 能 包 含 多 字 节 字 符 的 字 符 集 文 本 。 你 的 脚 本 所 使 用 的 字 符 串 处 理 , 带 有 这 种 每 个 898 第36 章 平 台 默 认 编 码 的 类 型 , 但 是 , 在 内 存 中 以 及 在 文 件 之 间 来 回 转 换 的 时 候 , 将 会 提 供 明 确 的 编 码 名 , 以 便 在str 对 象 和 不 同 的 方 案 之 间 来 回 转 换 。 尽 管Python 3.0 新 的str 类 型 确 实 实 现 了 想 要 的 字 符
30、 串/Unicode 结 合 , 但 很 多 程 序 仍 然 需 要 处 理 那 些 没 有 针 对 每 个 任 意 文 本 格 式 都 编 码 的raw 字 节 数 据 。 图 像 和 声 音 文 件 , 以 及 用 来 与 设 备 接 口 的 打 包 数 据 , 或 者 你 想 要 用Python 的struct 模 块 处 理 的C 程 序 , 都 属 于 这 一 类 型 。 因 此 , 为 了 支 持 真 正 的 二 进 制 数 据 的 处 理 , 还 引 入 了 一 种 新 的 类 型 , 即 bytes 。 在Python 2.X 中 , 通 用 的str 类 型 填 补 了 二
31、进 制 数 据 的 这 一 角 色 , 因 为 字 符 串 也 只 是 字 节 的 序 列 ( 单 独 的unicode 类 型 处 理 宽 字 符 串 ) 。 在Python 3.0 中 ,bytes 类 型 定 义 为 一 个8 位 整 数 的 不 可 变 序 列 , 表 示 绝 对 的 字 节 值 。 此 外 ,Python 3.0 的bytes 类 型 支 持 几 乎str 类 型 所 做 的 所 有 相 同 操 作 : 这 包 括 字 符 串 方 法 、 序 列 操 作 , 甚 至re 模 块 模 式 匹 配 ; 但 是 不 包 括 字 符 串 格 式 化 。 一 个Python 3
32、.0 bytes 对 象 其 实 只 是 较 小 整 数 的 一 个 序 列 , 其 中 每 个 整 数 的 范 围 都 在0 到255 之 间 ; 索 引 一 个bytes 将 返 回 一 个int , 分 片 一 个bytes 将 返 回 另 一 个bytes , 并 且 在 一 个bytes 上 运 行 内 置 函 数list 将 返 回 整 数 , 而 不 是 字 符 的 一 个 列 表 。 当 用 那 些 假 设 字 符 的 操 作 处 理bytes 的 时 候 ,bytes 对 象 的 内 容 被 假 设 为ASCII 编 码 的 字 节 ( 例 如 , isalpha 方 法 假
33、 设 每 个 字 节 都 是 一 个ASCII 字 符 代 码 ) 。 此 外 , 为 了 方 便 起 见 ,bytes 对 象 打 印 为 字 符 串 而 不 是 整 数 。 尽 管 如 此 ,Python 的 开 发 者 也 在Python 3.0 中 添 加 了 一 个bytearray 类 型 ,bytearray 是 bytes 类 型 的 一 个 变 体 , 它 是 可 变 的 并 且 支 持 原 处 修 改 。 它 支 持str 和bytes 所 支 持 的 常 见 的 字 符 串 操 作 , 以 及 和 列 表 相 同 的 很 多 原 处 修 改 操 作 ( 例 如 ,appe
34、nd 和extend 方 法 , 以 及 向 索 引 赋 值 ) 。 假 设 字 符 串 可 以 作 为raw 字 节 对 待 ,bytearray 最 终 为 字 符 串 数 据 添 加 了 直 接 原 处 可 修 改 的 能 力 , 这 在Python 2.0 中 不 通 过 转 换 为 一 个 可 变 类 型 是 不 可 能 做 到 的 , 并 且 也 是Python 3.0 的str 或bytes 所 不 支 持 的 。 尽 管Python 2.6 和Python 3.0 提 供 了 很 多 相 同 的 功 能 , 但 它 们 还 是 以 不 同 方 式 包 装 了 功 能 。 实 际
35、 上 , 从Python 2.6 到Python 3.0 的 字 符 串 类 型 映 射 并 不 是 直 接 的 ,Python 2.8 的 str 等 同 于Python 3.0 中 的str 和bytes , 并 且Python 3.0 的str 等 同 于Python 2.6 中 的str 和 Unicode 。 此 外 ,Python 3.0 的 可 变 的bytearray 是 独 特 的 。 然 而 , 实 际 上 , 这 种 不 对 称 并 不 像 听 上 去 那 么 令 人 生 畏 。 它 可 以 概 括 如 下 : 在Python 2.6 中 , 我 们 可 以 对 简 单
36、的 文 本 使 用str 并 且 对 文 本 的 更 高 级 的 形 式 使 用 二 进 制 数 据 和 unicode ; 在Python 3.0 中 , 我 们 将 针 对 任 何 类 型 的 文 本 ( 简 单 的 和Unicode ) 使 用str , 并 且 针 对 二 进 制 数 据 使 用bytes 或bytearray 。 实 际 上 , 这 种 选 择 常 常 由 你 所 使 用 的 工 具 决 定 , 尤 其 是 在 文 件 处 理 工 具 的 例 子 中 , 这 是 下 一 小 节 的 主 题 。Unicode 和字节字符串 899 文 本 和 二 进 制 文 件 文 件
37、I/O ( 输 入 和 输 出 ) 在Python 3.0 中 也 有 所 改 进 , 以 反 映str/bytes 的 区 分 以 及 对 编 码 Unicode 文 本 的 自 动 支 持 。Python 现 在 在 文 本 文 件 和 二 进 制 文 件 之 间 做 了 一 个 明 显 的 独 立 于 平 台 的 区 分 : 文 本 文 件 当 一 个 文 件 以 文 本 模 式 打 开 的 时 候 , 读 取 其 数 据 会 自 动 将 其 内 容 解 码 ( 每 个 平 台 一 个 默 认 的 或 一 个 提 供 的 编 码 名 称 ) , 并 且 将 其 返 回 为 一 个str
38、, 写 入 会 接 受 一 个 str , 并 且 在 将 其 传 输 到 文 件 之 间 自 动 编 码 它 。 文 本 模 式 的 文 件 还 支 持 统 一 的 行 尾 转 换 和 额 外 的 编 码 特 定 参 数 。 根 据 编 码 名 称 , 文 本 文 件 也 自 动 处 理 文 件 开 始 处 的 字 节 顺 序 标 记 序 列 ( 稍 后 详 细 介 绍 ) 。 二 进 制 文 件 通 过 在 内 置 的open 调 用 的 模 式 字 符 串 参 数 添 加 一 个b ( 只 能 小 写 ) , 以 二 进 制 模 式 打 开 一 个 文 件 的 时 候 , 读 取 其 数
39、 据 不 会 以 任 何 方 式 解 码 它 , 而 是 直 接 返 回 其 内 容 raw 并 且 未 经 修 改 , 作 为 一 个bytes 对 象 ; 写 入 类 似 地 接 受 一 个bytes 对 象 , 并 且 将 其 传 送 到 文 件 中 而 未 经 修 改 。 二 进 制 模 式 文 件 也 接 受 一 个bytearray 对 象 作 为 写 入 文 件 中 的 内 容 。 由 于str 和bytes 之 间 的 语 言 差 距 明 显 , 所 以 必 须 确 定 数 据 本 质 上 是 文 本 或 二 进 制 , 并 且 在 脚 本 中 相 应 地 使 用str 或by
40、tes 对 象 来 表 示 其 内 容 。 最 终 , 以 何 种 模 式 打 开 一 个 文 件 将 决 定 脚 本 使 用 何 种 类 型 的 对 象 来 表 示 其 内 容 : 如 果 正 在 处 理 图 像 文 件 , 其 他 程 序 创 建 的 、 而 且 必 须 解 压 的 打 包 数 据 , 或 者 一 些 设 备 数 据 流 , 则 使 用bytes 和 二 进 制 模 式 文 件 处 理 它 更 合 适 。 如 果 想 要 更 新 数 据 而 不 在 内 存 中 产 生 其 副 本 , 也 可 以 选 择 使 用bytearray 。 如 果 你 要 处 理 的 内 容 实
41、质 是 文 本 的 内 容 , 例 如 程 序 输 出 、HTML 、 国 际 化 文 本 或 CSV 或XML 文 件 , 可 能 要 使 用str 和 文 本 模 式 文 件 。 注 意 , 内 置 函 数open 的 模 式 字 符 串 参 数 ( 函 数 的 第 二 个 参 数 ) 在Python 3.0 中 变 得 至 关 重 要 , 因 为 其 内 容 不 仅 指 定 了 一 个 文 件 处 理 模 式 , 而 且 暗 示 了 一 个Python 对 象 类 型 。 通 过 给 模 式 字 符 串 添 加 一 个b , 我 们 可 以 指 定 二 进 制 模 式 , 并 且 当 读
42、 取 或 写 入 的 时 候 , 将 要 接 收 或 者 必 须 提 供 一 个bytes 对 象 来 表 示 文 件 的 内 容 。 没 有b , 我 们 的 文 件 将 以 文 本 模 式 处 理 , 并 且 将 使 用str 对 象 在 脚 本 中 表 示 其 内 容 。 例 如 , 模 式rb 、wb 和rb+ 暗 示 bytes , 而r 、w+ 和rt 暗 示str 。 文 本 模 式 文 件 也 处 理 在 某 种 编 码 方 案 下 可 能 出 现 在 文 件 开 始 处 的 字 节 顺 序 标 记 (b y t e order marker ,BOM ) 序 列 。 例 如
43、, 在UTF-16 和UTF-32 编 码 中 ,BOM 指 定 大 尾 还 是 小 900 第36 章 尾 格 式 ( 基 本 上 , 是 确 定 一 个 位 字 符 串 的 哪 一 端 最 重 要 ) 。 一 般 来 说 , 一 个UTF-8 文 本 文 件 也 包 含 了 一 个BOM 来 声 明 它 是UTF-8 , 但 并 不 保 证 这 样 。 当 使 用 这 些 编 码 方 法 来 读 取 和 写 入 数 据 的 时 候 , 如 果BOM 有 一 个 通 用 的 编 码 暗 示 或 者 如 果 提 供 一 个 更 为 具 体 的 编 码 名 来 强 制 这 点 的 话 ,Pyth
44、on 会 自 动 省 略 或 写 出BOM 。 例 如 ,BOM 总 是 针 对 “utf-16 ” 处 理 , 更 具 体 的 编 码 名 “u t f-16-l e ” 表 示 小 尾U T F-16 格 式 , 更 具 体 的 编 码 名 “u t f-8- sig ” 迫 使Python 在 输 入 和 输 出 上 分 别 都 针 对UTF-8 文 本 省 略 并 写 入 一 个BOM ( 通 用 名 称 “utf-8 ” 并 不 这 么 做 ) 。 我 们 还 将 在 本 章 后 面 的 “ 在Python 3.0 中 处 理BOM ” 一 节 中 介 绍 更 多 有 关BOM 和
45、文 件 的 内 容 。 首 先 , 让 我 们 探 讨Python 的 新 的Unicode 字 符 串 模 型 的 含 义 。 Python 3.0 中 的 字 符 串 应 用 让 我 们 再 看 一 些 例 子 , 这 些 例 子 展 示 了 如 何 使 用P y t h o n 3.0 字 符 串 类 型 。 提 前 强 调 一 点 : 本 节 中 的 代 码 都 只 在P y t h o n 3.0 下 运 行 和 使 用 。 然 而 , 基 本 的 字 符 串 操 作 通 常 在 Python 各 版 本 中 是 可 移 植 的 。 用str 类 型 表 示 的 简 单 的ASCII
46、 字 符 串 在Python 2.6 和Python 3.0 下 都 能 工 作 ( 并 且 确 实 像 我 们 在 本 书 第7 章 中 所 见 到 的 那 样 ) 。 此 外 , 尽 管Python 2.6 中 没 有bytes 类 型 ( 它 只 有 通 用 的str ) , 它 通 常 按 照 这 样 的 方 式 来 运 行 代 码 : 在Python 2.6 中 , 调 用bytes(X) 作 为str(X) 的 同 义 词 出 现 , 并 且 新 的 常 量 形 式b. 看 做 与 常 量 . 相 同 。 然 而 , 我 们 仍 然 可 能 在 一 些 个 别 的 例 子 中 遇
47、到 版 本 差 异 ; 例 如 ,Python 2.6 的bytes 调 用 , 不 允 许Python 3.0 中bytes 所 要 求 的 第 二 个 参 数 ( 编 码 名 称 ) 。 常 量 和 基 本 属 性 当 调 用str 或bytes 这 样 的 一 个 内 置 函 数 的 时 候 , 会 引 发Python 3.0 字 符 串 对 象 , 来 处 理 调 用open ( 下 一 小 节 介 绍 ) 所 创 建 的 一 个 文 件 , 或 者 在 脚 本 中 编 写 常 量 语 法 。 对 于 后 者 , 一 种 新 的 常 量 形 式bxxx ( 以 及 对 等 的Bxxx
48、) 用 来 创 建Python 3.0 中 的bytes 对 象 ,bytearray 对 象 可 能 通 过 调 用bytearray 函 数 来 创 建 , 这 会 带 有 各 种 可 能 的 参 数 。 更 正 式 地 说 , 在Python 3.0 中 , 所 有 当 前 字 符 串 常 量 形 式 ,xxx 、“xxx“ 和 三 引 号 字 符 串 块 , 都 产 生 一 个str ; 在 它 们 任 何 一 种 前 面 添 加 一 个b 或B , 则 会 创 建 一 个bytes 。 这 个 新 的b. 字 节 常 量 类 似 于 用 来 抑 制 反 斜 杠 转 义 的r. raw
49、 字 符 串 。 考 虑 在Python 3.0 中 运 行 如 下 语 句 : C:misc c:python30python B = bspam # Make a bytes object (8-bit bytes) S = eggs # Make a str object (Unicode characters, 8-bit or wider) type(B), type(S)Unicode 和字节字符串 901 (, ) B # Prints as a character string, really sequence of ints bspam S eggs bytes 对 象 实 际 上 是 较 小 的 整 数 的 一 个 序 列 , 尽 管 它 尽 可 能 地 将 自 己 的 内 容 打 印 为 字 符 : B0, S0 # Indexing returns