函数绑定(作用域解析) 主要发生在 语义分析阶段 和 字节码生成阶段,但关键的作用域信息会延续到运行时
Python 代码处理全流程
词法分析(Lexical Analysis)
生成 Token 流(如 def, x, =, 1 等)。
不涉及作用域分析。
语法分析(Syntax Analysis)
生成 AST(抽象语法树)。
例如将 def f(): x=1 解析为函数定义节点。
此时仅知道语法结构,未绑定作用域。
语义分析(Semantic Analysis)
关键阶段 1:确定变量和函数的作用域关系(LEGB 规则)。
标记变量是局部(Local)、闭包(Enclosing)、全局(Global)还是内置(Built-in)。
例如检测到 def f(): print(x) 时,确定 x 是自由变量,绑定到其定义时的作用域。
关键阶段 2:为嵌套函数生成闭包信息(如 closure)。
字节码生成(Bytecode Generation)
将 AST 转换为字节码,同时嵌入作用域信息:
全局变量引用 → LOAD_GLOBAL
局部变量 → LOAD_FAST
闭包变量 → LOAD_DEREF
例如 print(x) 的字节码会根据 x 的作用域选择不同的指令。
执行阶段(Runtime)
解释器执行字节码时,按预绑定的作用域规则(LEGB)查找变量。
闭包变量从 closure 中读取。
函数绑定的核心阶段
定义时的绑定(解析阶段):
语义分析:确定函数的作用域层级(是否嵌套、自由变量归属)。
字节码生成:生成带有作用域标记的指令(如 LOAD_GLOBAL 或 LOAD_DEREF)。
调用时的查找(执行阶段):
解释器根据字节码中的指令类型(如 LOAD_GLOBAL)动态查找变量,但查找逻辑由定义时的绑定决定。