深入理解Python命名空间:局部、全局与内置命名空间详解

Python通过名为命名空间的事物来记录变量的踪迹。命名空间就是一个字典,其中的键字是变量名,而字典的值是那些变量的值。实际上,能够像访问 Python 的字典那样去访问命名空间,稍后我们就会看到这一点。

深入理解Python命名空间:局部、全局与内置命名空间详解

[id_[id_562729351]3285996]内置命名空间是存在的,任何模块都能够访问它,并且它里面存放着内置的函数和异常。

当一行代码需要使用变量 x 的值时,Python 会在所有可用的名字空间中去查找该变量,查找顺序如下:

本地的,也就是特指当前函数或类的方法。若函数定义了一个局部变量 x,那么 Python 会使用这个变量,接着就会停止搜索。

在函数体内定义了一个新的函数,此函数处于封闭状态。

全局的(Global)指的是当前的模块。如果模块定义了一个名为 x 的变量、函数或者类,Python 就会使用这个变量,接着停止搜索。

内置的情况是对每个模块都为全局的。在进行最后的尝试时,Python 会假设 x 是内置函数或者变量。

如果 Python 在这些名字空间中找不到 x,它就会放弃查找。接着,它会引发一个 NameError 的异常,并且传递 There is no variable named ‘x’ 这样的信息。

像 Python 里的诸多事情那样,名字空间在运行时能够直接被访问。具体而言,局部名字空间可以借助内置的 locals 函数来进行访问。而全局(模块级别)名字空间则可以通过 globals 函数来进行访问。并且这两者返回的都是字典 dict 类型。

locals()介绍:

>>> def test(arg):
函数 foo 的局部名字空间中有两个变量,一个是 arg,它的值被传入函数;另一个是 z,它是在函数里定义的。
    z = 1
    print locals()
>>> test(4)
locals 会返回一个由名字和值组成的字典。该字典的键是字符串形式的变量名,而字典的值则是变量的实际值。
用 4 来调用 foo ,会打印出一个字典,这个字典包含函数的两个局部变量,即 arg (4) 和 z (1) 。
{'z': 1, 'arg': 4}
>>> test('doulaixuexi')
#locals 可以用于所有类型的变量。
{'z': 1, 'arg': 'doulaixuexi'}
>>>

globals()介绍:

>>> from sys import *
>>> print globals()
{'setrecursionlimit': in function setrecursionlimit>, 
'dont_write_bytecode': False, 
获取文件系统编码。: in function getfilesystemencoding>, 
'long_info'系统的长信息中包含每个数字的位数为15, sizeof_digit=2), 
'stdout': at 0x02110850>, 
'text': <function text at 0x02111A70>, 
'meta_path': [], 
'exc_clear': in function exc_clear>, 
'prefix': 'C:\\Python27', 'getrefcount': in function getrefcount

globals 函数会返回一个字典,这个字典包含了所有的全局变量,其中也包括所有被导入的变量。

locals()与globals()对比:

b = 5 # 定义一个全局变量
def test2():
    a=1
    locals()["a"] = 2  # 修改局部变量
    print "a=", a
    globals()["b"] = 6 # 修改全局变量
    print "b=", b
if __name__ == '__main__':
    test2()

输出:

a= 1
b= 6

locals() 所返回的是当前局部变量的一个深拷贝。当对 locals() 中的变量值进行修改时,实际上并不会对原变量本身产生任何影响。而 globals() 返回的是全局变量的字典,要是对其中的内容进行修改,其值就会真正地发生改变。

对于局部赋值需要注意如下:

myVar = 27
def myFunction(param1=123,param2="Python"):
    for key,val in locals().items():
        print "key %s : %s" % (key,str(val))
    myVar = myVar + 1
myFunction(123456,435465)

将会报错:

UnboundLocalError: local variable 'myVar' referenced before assignment

原因如下:

Python有这样的假设,在函数体内的某个地方对变量进行赋值时,Python 会将该名称添加到局部命名空间中。像语句 myVar = myVar + 1 这样的情况,它是对名称 myVar 进行赋值操作。Python 假设,无论在何处发生赋值这种行为,myVar 都属于函数 myFunction 的局部命名空间的一部分。Python尝试把 1 添加到 myVar 中,此时该名称处于局部命名空间内,然而它并没有关联值,所以会报错。

问题在于 Python 决定 myVar 出现在局部空间的时间,这在代码运行之前就发生了,也就是在 Python 运行到函数定义之前。因为在创建局部命名空间时(代码实际运行之前),Python 会对代码进行检查并填充局部命名空间。在 Python 运行那行代码之前,就已经发现了对 myVar 的赋值,并将其添加到了局部命名空间中。函数执行时,Python 解释器觉得 myVar 在局部命名空间里,然而却没有值,于是就会引发错误。

解决办法:在函数体内,若使用 global 语句把变量声明为全局变量,那么 Python 就不会在命名空间中为该变量创建局部名称。

myVar = 27
def myFunction(param1=123,param2="Python"):
    global myVar
    for key,val in locals().items():
        print "key %s : %s" % (key,str(val))
    myVar = myVar + 1
myFunction(123456,435465)

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

26阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读