Python变量名解析规则及相关技术疑问求证
变量作用域与LEGB规则的疑问
一些技术指南里未区分两个关键问题:
- 函数运行时,存在自身局部作用域及调用栈上层的若干作用域,每个作用域都有本地变量
- 函数定义时,同样存在带作用域的调用栈
那么在函数中引用变量时,变量名通过LEGB规则解析,该规则是基于函数定义时的调用栈,还是运行时的当前调用栈?我认为是前者,示例如下:
def f(): y = 'when_defined' def g(): print(y) return g def h(g): y = 'when_running' g() g = f() h(g)
输出:
>>> when_defined
但全局变量无需在函数定义时已存在,仍可被查找,示例如下:
def h(): print(x) x = 1 h()
输出:
>>> 1
我对该机制的理解如下:
- 函数定义时,会自动判定所用变量的类型:
- 若代码中存在写入操作或为参数,则为local变量
- 其他变量若来自嵌套作用域,则将对应名称的对象存入
fun.__closure__ - 剩余未分类变量,只能在global或builtins中查找
nonlocal和global关键字分别强制变量为“EGB中优先级最高的作用域”和“global作用域”
- 函数运行时,读取变量名的顺序:
- 先判断是否为已分类的local变量:若是则从
locals()获取(未赋值则报错) - 若是enclosed变量则从
fun.__closure__获取 - 之后查找
globals() - 最后查找
builtins()
- 先判断是否为已分类的local变量:若是则从
请问该理解是否正确?能否提供可查询该精确行为的权威资料?
另外,执行import时是否是运行一个新模块?由于模块定义无上层上下文,无法引用调用栈上层内容,仅独立运行后将其locals()加入当前locals()?
内容的提问来源于stack exchange,提问作者user87035
相关产品推荐
相关产品推荐

