一、概念介绍
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的,它的键就是变量名,它的值就是那些变量的值。
命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。
例如:
一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
二、命名空间的类型
- 内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
- 全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
- 局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
2.1、locals 内置函数locals(), 返回当前函数(方法)的局部命名空间
def func(a = 1):
b = 2
print(locals())
return a+b
func()
2.2、globals 内置函数globals(),返回当前module的命名空间
def func(a = 1):
b = 2
return a+b
func()
print(globals())
2.3、locals()和globals()有一个区别是,locals只读,globals可以写
def func(a = 1):
b = 2
return a+b
func()
glos = globals()
glos['new_variable'] = 3
print(new_variable)
def func(a = 1):
b = 2
locs = locals()
locs['c'] = 1
print(c)
func()
2.4、from module import 和 import module
使用 import module时,module 本身被引入,但是保存它原有的命名空间,所以我们需要使用 module.name 这种方式访问它的 函数和变量。
from module import这种方式,是将其它模块的函数或者变量引到当前的命名空间中,所以就不需要使用 module.name 这种方式访问其它的模块的方法了。
2.5、if __name__trick python中的module也是对象,所有的modules都有一个内置的属性__name__,模块的__name__属性的值取决于如何使用这个模块,如果import module,那么__name__属性的值是模块的名字。如果直接执行这个模块的话,那么__name__属性的值就是默认值__main__。
三、命名空间查找顺序
当一行代码要使用变量 x 的值时,Python 会到所有可用的名字空间去查找变量,按照如下顺序:
1、局部命名空间:特指当前函数或类的方法。如果函数定义了一个局部变量 x,或一个参数 x,Python 将使用它,然后停止搜索。
2、全局命名空间:特指当前的模块。如果模块定义了一个名为 x 的变量,函数或类,Python 将使用它然后停止搜索。
3、内置命名空间:对每个模块都是全局的。作为最后的尝试,Python 将假设 x 是内置函数或变量。
4、如果 Python 在这些名字空间找不到 x,它将放弃查找并引发一个 NameError 异常,如,NameError: name 'aa' is not defined。
info = "Adress : "
def func_father(country):
def func_son(area):
city= "Shanghai "
print(info + country + city + area)
city = " Beijing "
func_son("ChaoYang ");
func_father("China ")
四、命名空间的生命周期
不同的命名空间在不同的时刻创建,有不同的生存期。
1、内置命名空间在 Python 解释器启动时创建,会一直保留,不被删除。
2、模块的全局命名空间在模块定义被读入时创建,通常模块命名空间也会一直保存到解释器退出。
3、当函数被调用时创建一个局部命名空间,当函数返回结果 或 抛出异常时,被删除。每一个递归调用的函数都拥有自己的命名空间。
Python 的一个特别之处在于其赋值操作总是在最里层的作用域。赋值不会复制数据——只是将命名绑定到对象。删除也是如此:“del y” 只是从局部作用域的命名空间中删除命名 y 。事实上,所有引入新命名的操作都作用于局部作用域。
示例:
i=1
def func2():
i=i+1
func2();
由于创建命名空间时,python会检查代码并填充局部命名空间。在python运行那行代码之前,就发现了对i的赋值,并把它添加到局部命名空间中。当函数执行时,python解释器认为i在局部命名空间中但没有值,所以会产生错误。
def func3():
y=123
del y
print(y)
func3()
五、参考文档
1、https://www.runoob.com/python3/python3-namespace-scope.html
2、https://www.cnblogs.com/windlaughing/archive/2013/05/26/3100362.html
3、https://blog.csdn.net/u012436149/article/details/72819539
|