Python3 作用域和命名空间解释

译者:anxin
日期:2018-06-02

命名空间(Namespace)是一个名称系统,用来防止名称的混淆,我们所熟悉的命名空间例子是文件系统,一个文件夹就相当于一个命名空间,文件夹内的文件相当于名称,这样在不同的文件夹中创建名称相同的文件,不会产生冲突。

Python3 命名空间

Python3 命名空间是用来防止内部名称 Names(变量名,函数名,类名等)的冲突,Python3 命名空间使用字典(Dictionary)实现,即:字典里存放的是从名称到对象的映射。

Python3 中包含一下三种不同的命名空间:

  • Local 命名空间

    局部命名空间是函数级或类级的命名空间。Python3 在程序中调用每个函数时,都为调用的函数创建一个局部命名空间(调用类时也创建一个局部命名空间),并把函数内使用的名称存储到此命名空间中,当函数调用返回时,命名空间销毁。

  • Global 命名空间

    全局命名空间是模块级的命名空间。当 Python3 程序运行时导入一个模块,就创建一个全局命名空间,并把模块中使用的名称存储到命名空间中,命名空间到程序结束时销毁。

  • Build-in 命名空间

    Build-in 命名空间是用来保存 Python 3 內建函数和异常的命名空间。Python3 的 Build-in 命名空间在解释器开始运行时创建,在解释器结束时销毁。

Python3 作用域

Python3 作用域是在程序执行时,使用的一个名称它应该绑定到那个命名空间中的名称。在 Python3 程序运行时有如下嵌套的作用域:

  • 最内层的函数或类作用域包含局部名称,当在最内层的函数或类内引用名称时,Python3 首先在当前函数内寻找。
  • 包含最内层函数或类的外层函数或类,引用名称时,Python3 在包含当前名称的最临近的外层函数中寻找。
  • 模块级作用域,在此作用域中寻找当前模块中的全局名称。
  • 最外层作用域,在此作用域中寻找一些 Python3 內建的名称,在程序中最后去最外层作用域寻找名称。

Python3 命名空间和作用域的区别

命名空间:是一个静态的概念,它静态的为每个函数,类,模块定义了一个名称,这个名称在程序运行时用于区别其他的名称。

作用域:是一个动态的概念,它是程序运行时正在加载访问的域(你可以把它理解为正在加载访问的命名空间),根据命名空间的不同把程序运行时的域划分为多种域(作用域)。

Python3 作用域实例分析

如下通过一段程序来说明各种作用域,本段程序是 test.py 内的全部代码:

# 定义一个变量
a_var = 10
# 打印当前作用域内的名称
print("begin()-> ", dir())

# 定义一个函数 
def foo():
   b_var = 11
   # 打印当前函数作用域内的名称
   print("inside foo()-> ", dir())

# 调用函数
foo()

# 再一次打印当前作用域内的名称
print("end()-> ", dir())

如上程序的输出结果:

begin()-> ['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a_var']
inside foo()-> ['b_var']
end()-> ['__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a_var', 'foo']

注:dir() 的作用是输出当前作用域中所有可用的名称。

如上代码和输出解释:

  • 第一个 print() 输出的当前作用域(全局作用域)中的所有名称,包含了刚定义的 a_var
  • foo() 函数内的 print() 输出了本函数作用域内的所有名称,只有 b_var
  • 最后一个 print() 输出了目前作用域中包含的所有名称,其中有 foo,但是没有 b_var,因为 b_var 是在最内部的 foo() 函数作用域内的,不在当前的 foo() 函数的外层全局作用域内。

如上解释了函数的局部作用域和模块的全局作用域所能使用的名称的不同。

本文链接:/tutorial/python3/python3-zuoyongyu-mingmingkongjian

本文版权归知站所有,未经站长同意不得转载,谢谢尊重作者劳动成果!