标题
18 代币化
19 解析
20 AST
21 符号表
22 编译器通行证
23 代码对象
24 常量、名称和局部变量
25 字节码生成
26 字节码优化
  • 18. 代币化

    18. 代币化 标记化是 CPython 编译管道中的第一个结构阶段。 它接收 Python 源文本并生成令牌流。解析器使用该令牌流并从中构建语法结构。 在这个阶段,CPython 还不知道程序是否有意义。它只识别词汇单元:名称、数字、字符串、运算符、换行符、缩进和文件结束标记。 分词器将其转变为: python def add(a, b): return a + b 成这样的流: text NAME "def" NAME "add" LPAR "(" NAME "a" COMMA "," NAME "b" RPAR ")" COLON ":" NEWLINE "\n" INDENT " " NAME "return" NAME "a" PLUS "+" NAME "b" NEWLINE "\n" DEDENT "" ENDMARKER "" 确切的标记名称和解析器接口因 CPython 版本而异,但核心思想是稳定的。 Python 标准库通过以下方式公开了 Python 级别的分词器: tokenize ,而 CPython 的解析器在内部使用自己的 C 分词器。公众 tokenize…

  • 19. 解析

    19. 解析 解析是将令牌流转换为语法结构的阶段。 分词器识别词汇单元。解析器识别语法结构。它决定一个标记序列是否是一个有效的Python程序,并且当它有效时,构建一个抽象语法树。 对于这个来源: python def add(a, b): return a + b 标记器生成标记,例如: text NAME "def" NAME "add" LPAR "(" NAME "a" COMMA "," NAME "b" RPAR ")" COLON ":" NEWLINE "\n" INDENT " " NAME "return" NAME "a" PLUS "+" NAME "b" NEWLINE "\n" DEDENT "" ENDMARKER "" 解析器给出这些标记结构: text Module FunctionDef name="add" arguments arg "a" arg "b" body Return BinOp Name "a" Add Name "b" 差异很重要。标记化知道 def…

  • 20. AST

    #20. AST 抽象语法树,通常称为AST,是Python源代码解析后的结构化表示。 标记器生成扁平的标记流。解析器识别语法。 AST 将结果记录为语句和表达式的树。 对于这个来源: python x = 1 + 2 AST 的形状如下:```text Module Assign targets: Name id="x", ctx=Store value: BinOp left: Constant value=1 op: Add right: Constant value=2 ## 20.1 在编译管道中的位置 AST 位于解析和编译器分析之间。 ``` text source bytes ↓ tokenization ↓ parsing ↓ AST ↓ AST validation ↓ symbol table ↓ compiler ↓ code object ↓ bytecode execution ``` 解析器构建 AST 。后续阶段会消耗它。 AST 回答以下问题: ``` text What statements…

  • 21. 符号表

    21.符号表 解析生成 AST 后,CPython 执行范围分析。 此阶段构建符号表。 符号表记录名称在每个范围内的行为方式。它确定名称是本地名称、全局名称、自由名称、单元名称、参数名称、导入名称、注释名称还是从嵌套范围引用的名称。 对于这个来源:```python x = 10 def outer(): y = 20 def inner(): return x + y return inner 符号表阶段决定:```text x global from inner y free variable in inner y cell variable in outer inner local variable in outer outer global variable in module ```这种分析至关重要,因为字节码的生成依赖于它。加载局部变量使用与加载全局变量或闭包变量不同的字节码。 ## 21.1 在编译管道中的位置 符号表阶段位于 AST 构建和字节码生成之间。```text source ↓ tokenization ↓ parsing ↓ AST ↓ symbol table analysis ↓ compiler ↓…

  • 22. 编译器通行证

    22. 编译器通行证 编译器将 AST 和符号表信息转换为可执行代码对象。 早期阶段回答结构性问题。```text id="lfk0j9" tokenizer: What lexical units are in the source? parser: What syntax tree do these tokens form? symbol table: What scope does each name belong to? 编译器回答执行问题。 text id="ju2gsy" Which bytecode instructions should be emitted? Which constants belong in co_consts? Which names belong in co_names? Which local variables belong in co_varnames? Where should jumps go? How large can the evaluation stack grow? Which exception…

  • 23. 代码对象

    23. 代码对象 代码对象是 CPython 的可执行 Python 代码的编译表示。 它包含字节码和元数据。解释器可以执行它,但代码对象本身不携带运行时状态,例如全局变量、默认参数、闭包单元或绑定方法。 对于这个来源: python def add(a, b): return a + b 函数对象 add 包含一个代码对象:```python code = add. code print(code.co_name) print(code.co_varnames) print(code.co_consts) print(code.co_names) ## 23.1 在编译管道中的位置 代码对象是编译的输出。 ``` text source text ↓ tokenization ↓ parsing ↓ AST ↓ symbol table ↓ compiler ↓ code object ↓ frame execution ``` 代码对象是编译器和解释器之间的切换。 编译器生成代码对象。 评估循环执行帧内的代码对象。 ## 23.2 代码对象与函数对象 函数对象包装了代码对象。 例子: ``` python def f ( x ): return…

  • 24.常量、名称和局部变量

    24. 常量、名称和局部变量 代码对象不会将 Python 源代码存储为文本。它存储紧凑表和通过索引引用这些表的字节码指令。 最重要的三个表是:```text id="mx2a9w" co_consts co_names co_varnames 对于这个函数: ``` python id = "wg80pj" def f ( a ): b = len ( a ) return b + 1 ``` CPython 存储: ``` text id = "jxh1ou" constants : None 1 names : len local variables : a b ``` 然后字节码指令通过索引引用这些条目。 ## 24.1 在编译管道中的位置 常量、名称和局部变量在编译期间组装。 ``` text id = "la84x8" AST ↓ symbol table ↓ compiler ↓ instruction…

  • 25. 字节码生成

    25. 字节码生成 字节码生成是 CPython 将结构化语法转换为可执行虚拟机指令的阶段。 解析器构建 AST。 符号表决定范围行为。 然后编译器发出实现 Python 语义的字节码指令。 对于这个来源: python id="bjlwm8" def add(a, b): return a + b CPython 生成的字节码形状如下: text id="plhxq4" LOAD_FAST a LOAD_FAST b BINARY_OP + RETURN_VALUE 确切的指令名称和格式因 Python 版本而异,但模型保持稳定:```text id="ecx81v" bytecode is a low-level instruction stream executed by the CPython virtual machine 字节码生成发生在 AST 构建和范围分析之后。 ``` text id = "5v2o9v" source ↓ tokenization ↓ parsing ↓ AST ↓ symbol table ↓ bytecode generation ↓…

  • 26.字节码优化

    26.字节码优化 字节码优化是代码对象准备好执行之前的最后清理和细化阶段。 早期的编译器阶段决定程序的含义并发出指令。优化试图使这些指令更小、更简单或更快,同时保留 Python 语义。 例如: python id="u88pli" x = 1 + 2 可以像编写一样编译:```python id="k8v2ef" x = 3 但这: ``` python id = "lbwhpl" x = a + b ``` 无法折叠,因为 ` a ` 和 ` b ` 是运行时值。它们的类型可以定义任意行为 `+` 。 ## 26.1 在编译管道中的位置 优化发生在字节码生成之后或期间,具体取决于优化的类型。 ``` text id = "olp5um" source ↓ tokenization ↓ parsing ↓ AST ↓ symbol table ↓ instruction generation ↓ optimization ↓ assembly ↓ code object…