名称空间与作用域
名称空间
名称空间:(namespace)存放名字的地方,是对栈区的划分,听了一种在相同项目中避免名字冲突的方法
有了名称空间之后我们就可以在栈区存放相同的名字,详细的名称空间分为三种
1.1 内置名称空间
存放的是python解释器内置的名字 英文为 built-in
>>> print
>>> input
存活周期:python解释器启动则产生,python解释器关闭则销毁
1.2 全局名称空
只要不是函数内定义、也不是内置的、剩下的都是全局名称空间的名字,即模块中的变量,包括函数、类、其它导入模块、模块级的变量和常量 英文为 global
import os # 模块
x = 10. # 变量名
if 13 > 3:
y = 20 # 也属于全局名称空间
def func(): # 函数名
a = 1
b = 2
存活周期:该文件执行则产生,文件运行完毕之后销毁
1.3 局部名称空间
在函数内定义的名称,包括函数参数,局部定义的变量 英文为local
x = 10 # x为全局名称
def func():
a = 20 # a是局部名称
def func2():
b = 30. # b是内嵌的局部名称
存活周期:调用执行函数体代码时存活,调用完毕后销毁
1.4 名称空间查找优先级
在当前位置向上一层一层查找
内置名称空间=>全局名称空间=>局部名称空间
如果当前局部名称空间:局部的命名空间去-> 全局命名空间 -> 内置命名空间
如果当前在全局名称空间:全局名称空间=>内置名称空间
注意:无法向内查找,只能向外层一层一层查找
作用域
作用域即作用范围
全局作用域:内置名称空间,全局名称空间
1、全局存活
2、全局有效,被所有函数共享
局部作用域:局部名称空间
1、临时存活
2、局部有效,函数内有效
-
L(Local):最内层,包含局部变量,比如一个函数/方法内部。
-
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
-
G(Global):当前脚本的最外层,比如当前模块的全局变量。
-
B(Built-in): 包含了内建的变量/关键字等,最后被搜索。
注意:名称空间的嵌套关系是以函数定义为准生成的,与调用位置无关
def foo():
print(x)
def bar():
x = 111
foo()
x = 100
bar() # bar()的输出结果为100
global 与 nonlocal关键字
当局部作用域想修改成为全局作用域变量时,就需要用到global关键字
x = 1
def func():
global x # global关键字声明
x = 100
print(x)
print(x) # 此时全局变量x已经被修改 x = 100
func() # 100
nonlocal关键字用来修改嵌套作用域,即enclosing作用域,通俗的来说,即嵌套的外一层的变量,不会修改全局中的变量
def outer():
x = 10
def inner():
nonlocal x # nonlocal 关键字声明
x = 555
print(x)
inner()
print(x)
outer() # 输出结果为555 555