VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • Python命名空间实例解析

Python的命名空间是Python程序猿必须了解的内容,对Python命名空间的学习,将使我们在本质上掌握一些Python中的琐碎的规则。

接下来我将分四部分揭示Python命名空间的本质:一、命名空间的定义;二、命名空间的查找顺序;三、命名空间的生命周期;四、通过locals()和globals() BIF访问命名空间

重点是第四部分,我们将在此部分观察命名空间的内容。

一、命名空间

Python使用叫做命名空间的东西来记录变量的轨迹。命名空间是一个 字典(dictionary) ,它的键就是变量名,它的值就是那些变量的值。

A namespace is a mapping from names to objects. Most namespaces are currently implemented as Python dictionaries。

 

在一个 Python 程序中的任何一个地方,都存在几个可用的命名空间。

    1、每个函数都有着自已的命名空间,叫做局部命名空间,它记录了函数的变量,包括函数的参数和局部定义的变量。

    2、每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。

    3、还有就是内置命名空间,任何模块均可访问它,它存放着内置的函数和异常。

 

二、命名空间查找顺序

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

    1、局部命名空间:特指当前函数或类的方法。如果函数定义了一个局部变量 x,或一个参数 x,Python 将使用它,然后停止搜索。

    2、全局命名空间:特指当前的模块。如果模块定义了一个名为 x 的变量,函数或类,Python 将使用它然后停止搜索。

    3、内置命名空间:对每个模块都是全局的。作为最后的尝试,Python 将假设 x 是内置函数或变量。

    4、如果 Python 在这些名字空间找不到 x,它将放弃查找并引发一个 NameError 异常,如,NameError: name 'aa' is not defined。

 

嵌套函数的情况:

    1、先在当前 (嵌套的或 lambda) 函数的命名空间中搜索

    2、然后是在父函数的命名空间中搜索

    3、接着是模块命名空间中搜索

    4、最后在内置命名空间中搜索

 

示例:

1
2
3
4
5
6
7
8
9
10
info= "Adress : "
 def func_father(country):
     def func_son(area):
         city= "Shanghai " #此处的city变量,覆盖了父函数的city变量
         print(info+ country+ city+ area)
     city= " Beijing "
     #调用内部函数
     func_son("ChaoYang ");
   
 func_father("China ")

 

输出:Adress : China Shanghai ChaoYang

以上示例中,info在全局命名空间中,country在父函数的命名空间中,city、area在自己函数的命名空间中

 

 

三、命名空间的生命周期

不同的命名空间在不同的时刻创建,有不同的生存期。

    1、内置命名空间在 Python 解释器启动时创建,会一直保留,不被删除。

    2、模块的全局命名空间在模块定义被读入时创建,通常模块命名空间也会一直保存到解释器退出。

    3、当函数被调用时创建一个局部命名空间,当函数返回结果 或 抛出异常时,被删除。每一个递归调用的函数都拥有自己的命名空间。

 

  Python 的一个特别之处在于其赋值操作总是在最里层的作用域。赋值不会复制数据——只是将命名绑定到对象。删除也是如此:"del y" 只是从局部作用域的命名空间中删除命名 y 。事实上,所有引入新命名的操作都作用于局部作用域。

示例:

i=1

def func2():

   i=i+1

 

func2();

#错误:UnboundLocalError: local variable 'i' referenced before assignment

由于创建命名空间时,python会检查代码并填充局部命名空间。在python运行那行代码之前,就发现了对i的赋值,并把它添加到局部命名空间中。当函数执行时,python解释器认为i在局部命名空间中但没有值,所以会产生错误。

def func3():

  y=123

  del y

  print(y)

func3()

#错误:UnboundLocalError: local variable 'y' referenced before assignment

#去掉"del y"语句后,运行正常

 

四、命名空间的访问

1、局部命名空间可以 locals()  BIF来访问。

locals 返回一个名字/值对的 dictionary。这个 dictionary 的键是字符串形式的变量名字,dictionary 的值是变量的实际值。

示例:

def func1(i, str ):

   x = 12345

   print(locals())

 

func1(1 , "first")

输出:{'str': 'first', 'x': 12345, 'i': 1}

 

2、全局 (模块级别)命名空间可以通过 globals() BIF来访问。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'''Created on 2013-5-26'''
  
import copy
from copyimport deepcopy
  
gstr= "global string"
  
def func1(i, info):
    x= 12345
    print(locals())
  
func1(1 ,"first")
  
if __name__== "__main__":
    print("the current scope's global variables:")
    dictionary=globals()
    print(dictionary)