命名空间的小弟作用域
在这要明确一个观点, 在 Python 中万物皆对象, 而变量指向的就是对象.
变量可以是 类名, 函数名, 储存数据的变量......
对象可以是 类 , 被封装的一段代码(函数), 数据......
命名空间
命名空间是从名字到对象的映射. 在 Python 大多数命名空间目前以字典的形式实现. 变量名是 "键", 对象 (内置函数, 内置常量, 内置类型, 函数, 类, 变量) 是 "值".
各个命名空间是独立的, 没有任何关系的, 所以一个命名空间中不能有重名, 但不同的命名空间是可以重名而没有任何影响.
命名空间都是有创建时间和生存期的. 对于 Python built-in namespace(内置命名空间 -- 内置函数, 内置常量, 内置类型)组成的命名空间, 它在 Python 解释器启动的时候被创建, 在解释器退出的时候才被删除;
对于一个 Python 模块的 global namespace(全局变量), 它在这个模块被 引用的时候创建, 在解释器退出的时候退出;
对于一个函数的 local namespace(局部作用域), 它在函数每次被调用的时候创建, 函数返回的时候被删除.
作用域
作用域只是命名空间表示大小 (适用范围) 的属性.
作用域是 Python 程序 (文本) 的某一段或某些段, 在这些地方, 某个命名空间中的名字可以被直接引用. 这个作用域就是这个命名空间的作用域.
python 中的作用域分 4 种情况:
L:local, 局部作用域, 即函数中定义的变量;
E:enclosing, 嵌套的父级函数的局部作用域, 即包含此函数的上级函数的局部作用域, 但不是全局的;
G:globa, 全局变量, 就是模块级别定义的变量;
B:built-in, 系统固定模块里面的变量, 比如 int, bytearray 等
搜索变量的优先级顺序
局部作用域>外层作用域>当前模块中的全局 > python 内置作用域, 也就是 L>E>G>B.
- B = str("B:built-in 内置作用域")
- G = "G:globa, 全局变量, 就是模块级别定义的变量"
- print(B) # 当前模块中的全局 > python 内置作用域 找 B
- print(G) # 当前模块中的全局 找 G
- print(E) # 找不到 E
- print(L) # 找不到 L
- def f():
- E = "E:enclosing, 嵌套的父级函数的局部作用域"
- print(B) # 外层作用域>当前模块中的全局 > python 内置作用域 找 B
- print(G) # 外层作用域>当前模块中的全局 找 G
- print(E) # 外层作用域 找 E
- print(L) # 找不到 L
- def z ():
- L = "L:local, 局部作用域, 即函数中定义的变量"
- print(B) # 作用域局部>外层作用域>当前模块中的全局 > python 内置作用域 找 B
- print(G) # 作用域局部>外层作用域>当前模块中的全局 找 G
- print(E) # 作用域局部>外层作用域 找 E
- print(L) # 作用域局部 找 L
注意: 在 Python 中, 只有模块 (module), 类(class) 以及函数 (def,lambda) 才会引入新的作用域, 其它的代码块 (如 if,try,for 等) 是不会引入新的作用域的
变量的修改
在 "作用域局部>外层作用域>当前模块中的全局 > python 内置作用域" 中, 更内层的作用域不可直接修改外层的作用域的变量, 要修改要用到 global 关键字 和 nonlocal 关键字
global 关键字
当修改的变量是在全局作用域 (global 作用域) 上的, 就要使用 global 先声明一下.
nonlocal 关键字
global 关键字声明的变量必须在全局作用域上, 不能嵌套作用域上, 当要修改嵌套作用域 (enclosing 作用域, 外层非全局作用域) 就需要 nonlocal 关键字了
- B = str("B:built-in 内置作用域")
- G = "G:globa, 全局变量, 就是模块级别定义的变量"
- def f():
- E = "E:enclosing, 嵌套的父级函数的局部作用域"
- def z ():
- L = "L:local, 局部作用域, 即函数中定义的变量"
- global B
- B = "修改全局作用域的变量"
- nonlocal E
- E = "修改嵌套作用域的变量"
欢迎评论, 番茄, 鸡蛋都砸过来吧!!!
来源: https://www.cnblogs.com/barkingpig/p/9202975.html