命名空间:名称与对象之间的关系,可以将命名空间看作是字典,其中键:名称,值:对像;
注意:命名空间不共享名称。
当有多个命名空间时,可以按照既定的名称解析规则,来解析名称。按照定义的搜索顺序,在多个命名 空间中查找名称;
知识点一:
在python中的变量名,在第一次赋值时,将被创建,而且变量名只有被创建了,才能使用,否则会报错;
知识点二:
在python中,只有模块,函数,类才可以引入新的作用域,其它代码不会引入新的作用域;
知识点三:
每一个模块都可以看做是一个全局作用域,python中是没有类似c++中可以存活整个项目的作用域;
python中作用域仅限于单个模块;
知识点四:
被正确赋值的变量除非声明为global,否则均为本地变量;“变量名只有被赋值才可以被声明为本地变量”;
变量名解析规则:LEGB(Local , Inclosing, Global , Built_In )
L:局部的
E:封闭的
G:全局的
B:内置的
L ---->E------>G------->B;
也可以理解为:变量名分三个作用域进行查找:本地==>函数内==》全局===》内置
代码理解:
if 语句并未引入新的局部作用域 , 变量i 仍然在全局作用域中,故对print可见;
>>> if True:
i = 4
>>> print i
4
>>>
调用函数fun1():
>>> def fun1():
i = 12
print i
>>> fun1()
12
>>>
声明变量i , 且i被赋值为12,则其被创建在函数命名空间,即局部命名空间。执行fun()时,会在本地(函数内部)查找i(局部变量)。
调用函数fun2():
>>> i = 34
>>> def fun2():
i = i + 1
print i
>>> fun2()
Traceback (most recent call last):
File "<pyshell#300>", line 1, in <module>
fun2()
File "<pyshell#299>", line 2, in fun2
i = i + 1
UnboundLocalError: local variable 'i' referenced before assignment
>>>
首先在定义fun2()之前,定义全局变量(global)i = 34 ,然后定义fun2(),同样在局部命名空间函数内,定义了局部变量i ;
但是在执行fun2()后出现:
UnboundLocalError: local variable 'i' referenced before assignment
错误。
所以即使定义了同名的全局变量,但是函数fun2()并未如预期的那样,现在局部命名空间查找变量,未找到再到全局命名空间查找;
python提出如下假设,如果在函数体内的任何地方对变量赋值,则python将名称添加到局部命名空间中。语句i=i+1对对象i进行赋值。
python假设无论在何处发生赋值,i都是函数func局部命名空间的一部分。当python尝试把1跟i相加时,该i名称在局部命名空间中,但它没有关联值,所以python报错。
问题出现在python何时决定使i出现在局部命名空间中。
实际i出现在局部命名空间中发生在代码运行前,即,在python运行到函数定义之前。由于创建命名空间时,python会检查代码并填充局部命名空间。在python运行那行代码之前,就发现了对i的赋值,并把它添加到局部命名空间中,当函数执行时,python解释器认为i在局部命名空间中但没有值,所以会产生错误。
调用函数fun3():
>>> i = 45
>>> def fun3():
i = 23
print i
>>> print i
45
>>> fun3()
23
>>>
print i -->45:在本地(全局作用域)查找变量i,找到输出;fun3()-->23:在本地命名空间找到变量i,输出;
调用fun4():
>>> i = 123
>>> def fun4():
print i
>>> fun4()
123
>>>
函数fun4():并未出现fun2()中的问题,因为函数内并没有进行赋值创建,fun2()内定义了局部变量i,但是其没有被赋值,或者说赋值对象(准确值)不存在;
fun4()内执行print i;局部查找i并未找到------>在全局命名空间找到同名i,且i = 123;输出;
调用函数fun5():
>>> def fun5():
print j
>>> fun5()
Traceback (most recent call last):
File "<pyshell#321>", line 1, in <module>
fun5()
File "<pyshell#320>", line 2, in fun5
print j
NameError: global name 'j' is not defined
>>>
运行结构显示:global name ' j' is not defined
python首先在函数fun5() 的本地作用域查找变量j ,查找失败;继续道全局作用域和内置作用域中查找仍然失败;最终抛出NameError;
通过global将变量声明为全局域变量:
>>> var = 2324
>>> def fun6():
global var
print var
var = var + 45
print var
>>> print var
2324 #全局var
>>> fun6()
2324 #通过global ,声明为全局变量域2324
2369 #对全局var + 45
>>>
除了通过global对全局变量进行访问外,还可以在函数中引用自身module,然后通过模块名.变量名的方式访问全局变量
thismodule.py
var = 99
def local():
var = 0
print var #local var
def globl():
global var #global var
var += 1
print var #global
def globl2():
var = 0
import thismod
thismod.var += 2 #global var
print var #local var
def globl3():
var = 0
import sys
glob = sys.modules['thismod']
glob.var += 3 #global var += 3
print var # local var = 0
执行thismodule.py
>>> ================================ RESTART ================================
>>> import thismodule
>>> thismodule.val
100 #全局
>>> thismodule.local()
0 #局部
>>> thismodule.globl()
101 #全局
>>> thismodule.val
101 #全局
>>> thismodule.globl2()
23 #局部
>>> thismodule.val
103 #全局
>>> thismodule.globl3()
0 #局部
>>> thismodule.val
106 #全局
>>>