【ZZ】python命名空间与做用域

python命名空间与做用域

命名空间是名称与对象之间的关系,能够将命名空间看作是字典,其中的键是名称,值是对象。

命名空间不共享名称。

在命名空间中的名称能将任何python对象做为值,在不一样的命名空间中相同的名称能够与不一样的对象相关联。可是,若是存在名称解析协议,则多个命名空间能够一块儿工做来解析名称。也就是说,若是有多个命名空间(老是有的),那么能够定义搜索的顺序,依次在不一样的命名空间里来查找某个名称(或确认其不存在于任何承认的命名空间)。在python中,将这一过程定义为做用域。
做用域搜索规则:LEGB

L:局部的(local)

E:封闭的(Enclosing)

G:全局的(Global)

B:内置的(Built-in)
1、局部命名空间

函数内部的命名空间,在调用函数的时候生成,调用结束时消失。当局部命名空间有效时,它是第一个用于检查某个名字存在性的命名空间。若是在局部命名空间内找到该名称,则返回与名字相关联的对象,反之提示出错。
2、全局命名空间

python在模块中维护命名空间,模块是一些python文件--包含函数等对象,而且能够导入其余程序使用。当某个模块被导入以后,该模块同时引入了一个命名空间,其中包含模块中全部的名称和关联的对象,能够经过存储在没个模块中的__dict__来查看这个命名空间,换句话说,字典就是这个模块的命名空间。

若是想要引用给模块中的对象,要使用点符号将名称和模块名称关联,这其实是要求将对象与该模块中的名称相关联。

当python启动解释器时,它将自动导入两个模块,即模块__main__和__built-ins__。__main__模块是默认的全局模块,全部新对象都存储在其中。能够经过函数globals来访问该命名空间的字典。子啊平python解释器中经过输入用户交互时,globals是有效的命名空间。
1.局部赋值规则

python中有一种称为“本地赋值”的规则很是有趣。若是在函数内的任何地方进行局部赋值,则该赋值只在当前活动的命名空间中建立名称。有时这将产生反作用,举例以下:


>>> value = 27
>>> def func(param1,param2):
    for key,val in locals().items():
        print (key,val)
    value = value + 1

    
>>> func(98765,43210)
param1 98765
param2 43210
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    func(98765,43210)
  File "<pyshell#6>", line 4, in func
    value = value + 1
UnboundLocalError: local variable 'value' referenced before assignment
>>>

首先经过赋值在全局命名空间中建立了变量value。也许你会认为,当函数值加1是会先在局部的命名空间中查找变量,没法找到时在全局命名空间中找到该名字。能够并非这样。

python提出以下假设,若是在函数体内的任何地方对变量赋值,则python将名称添加到局部命名空间中。语句value=value+1对对象value进行赋值。python假设不管在何处发生赋值,value都是函数func局部命名空间的一部分。当python尝试把1跟value相加时,该value名称在局部命名空间中,但它没有关联值,因此python报错。

问题在于python什么时候决定使value出如今局部命名空间中。实际value出如今局部命名空间中发生在代码运行前,即,在python运行到函数定义以前。因为建立命名空间时,python会检查代码并填充局部命名空间。在python运行那行代码以前,就发现了对value的赋值,并把它添加到局部命名空间中,当函数执行时,python解释器认为value在局部命名空间中但没有值,因此会产生错误。


2.global语句

有一个方法能够解决上面的问题。若是在函数体内,使用global语句将变量声明为全局变量,那么python不会为该变量在命名空间中建立局部名称。
3、内置模块

遵循LEGB搜索规则,若是python不能在局部命名空间中找到某个名称,则会在全局命名空间中继续寻找,它寻找到的将是python的内置名称。

built-in模块和其余模块同样,都具备__dict__属性,这就是模块的命名空间
4、封闭式变量

“封闭式”的做用域规则适应于函数定义函数时,也就是说,在函数体内定义了一个新的函数。这个函数体内的函数是外函数的局部命名空间中的一部分,意味着只有在外函数执行期间才可以运行。完整的LEGB规则是先检查局部命名空间,以后是封闭在局部命名空间中的其余函数,以后是全局命名空间,在最后之内置命名空间结束。
python

相关文章
相关标签/搜索