编码 Python 源代码文件
编码 Python 源代码文件
原文:https://medium.com/hackernoon/encoding-the-python-source-code-file-445722836813
GitHub 上大约有1500 万行Python 代码,以一种形式的变体开始:# -*- coding:<some encoding> -*-。对于任何学习 Python 的人来说,这似乎是另一个单行的“注释”。当我开始用 Python 编程时,我确实是这样看的。然而,我很快意识到,这里面有一些神秘和深奥的东西。这是某种被所有代码库的 Python 开发者使用的 特殊注释 。在本文中,我将尝试分解这行代码背后的概念。
我们的工具包
ASCII: 一个字符集,使用 32 到 127 之间的数字来表示内存中每一个好的旧的无重音英文字母。字母“A”由 65 代表,而 32 代表一个“空格”。
Unicode: Unicode 是一个勇敢的努力,它创造了一个单一的字符集,包括了地球上所有合理的书写系统,也包括一些像克林贡语一样的虚构系统。在 Unicode 中,一个字母映射到一个叫做代码点的东西,这仍然只是一个理论概念。
UTF-8: 这是一种处理字符存储问题的编码。在 UTF-8 中,从 0 到 127 的每个代码点都存储在单个字节中。只有 128 及以上的代码点使用 2,3,事实上,多达 6 个字节存储。这有一个很好的副作用,即英语文本在 UTF-8 中看起来和在 ASCII 中完全一样。
在不知道字符串使用什么编码的情况下拥有它是没有意义的。—乔尔·斯波尔斯基
TL;DR——如果你有一个字符串,在内存或文件中,你必须知道它是什么编码,否则你不能正确地解释它或显示给用户。
源代码文件编码
每当您需要在定义文字时输入任何非 ASCII 字符,即不能通过 ASCII 码 表示的字符(例如,带重音的英文字母、希腊符号),Python 解释器不知道使用何种编码来表示该字符。因此,定义编码增强了源代码中 Unicode 字面量的解释,并使得在 Unicode 感知编辑器中直接使用例如 UTF-8 来编写 Unicode 字面量成为可能。这就是我们的 特别评论 进入画面的地方!
如果 Python 脚本的第一行或第二行中的一个注释与正则表达式
*coding[=:]\s*([-\w.]+)*匹配,这个注释将被处理为一个编码声明;这个表达式的第一组命名源代码文件的编码。编码声明必须单独占一行。如果是第二行,第一行也必须是注释专用行。
因此,只要正则表达式匹配,编码语句的所有变体都有效。参考 PEP 263 获取示例。
注意:从 Python 3.0 开始,如果没有找到编码声明,默认编码是 UTF-8。
说够了,给我看看代码
我们将使用上述文件中代码的一些变体来理解文件中编码的重要性。所以,我建议你复制并保存这个 Python 文件。进行下面描述的实验,并尝试推理你的观察。
- 实验 01: 使用 Python2 解释器运行这个文件。
- 实验 02: 使用 Python3 解释器运行这个文件。
- 实验 03: 去掉 L01(读第 1 行)。使用 Python2 解释器运行更新的文件。
- 实验 04: 去掉 L01(读第 1 行)。使用 Python3 解释器运行更新的文件。
观察
- 实验 01:unicode 字符串“表示”中非 ASCII 字符的码位。
- 实验 02: 原因为
AttributeError加成:用encode代替decode修改 L03 并执行文件。 - 实验 03: 似乎很有道理,不是吗?
- 实验 04: 不是所有的观察结果都和实验 02 的一样吗?
如果你在理解这些观察时仍然有困难,或者我可能跳过了一些重要的观察,请在评论中告诉我。
吸取的教训
- 如果您打算使用 UTF-8 编码只编写 Python3 特定的代码,就不需要使用这一行。
- 在所有其他情况下,建议在 Python 文件的顶部提及编码。这有两个好处: 1。在你的代码中显式。Python2 和 Python3 之间的兼容性