一、命名空间
白话一点讲:命名空间是对变量名的分组划分。
不同组的相同名称的变量视为两个独立的变量,因此隶属于不同分组(即命名空间)的变量名可以重复。
命名空间可以存在多个,使用命名空间,表示在该命名空间中查找当前名称。
二、 LEGB 原则
LEGB含义解释:
L-Local(function);函数内的名字空间
E-Enclosing function locals;外部嵌套函数的名字空间(例如closure)
G-Global(module);函数定义所在模块(文件)的名字空间
B-Builtin(Python);Python内置模块的名字空间
LEGB规定了查找一个名称的顺序为:local–>enclosing function locals–global–>builtin
In [1]: x=1
In [2]: def foo():
...: x=2
...: def inner_foo():
...: x=3
...: print('locals:',x)
...: inner_foo()
...: print('enclosing function locals:',x)
...:
In [3]: foo()
locals: 3
enclosing function locals: 2
In [4]: print('global:',x)
global: 1
稍加改动
In [5]: x=1
In [6]: def foo():
...: x=2
...: def inner_foo():
...: # x=3
...: print('locals:',x)
...: inner_foo()
...: print('enclosing function locals:',x)
...:
In [7]:
In [7]: foo()
locals: 2
enclosing function locals: 2
In [8]: print('global',x)
global 1
可以发现:当注释掉x = 3
以后,函数innerfoo
内部查找到的x是x = 2
。
在上述两个例子中,从内到外,依次形成四个命名空间:
-
def innerfoo():
:Local
, 即函数内部命名空间; -
def foo():
:Enclosing function locals
;外部嵌套函数的名字空间 -
module
(文件本身):Global(module)
;函数定义所在模块(文件)的名字空间 -
Python内置模块
的名字空间:Builtin
x = 3
属于函数内部命名空间,当被注释掉之后,函数innerfoo
内部通过print x
使用x这个名称时,触发了名称查找动作。
首先在Local命名空间
查找,没有找到,然后到Enclosing function locals命名空间
查找,查找成功,然后调用。
参考资料:
Python LEGB规则