>>> 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