📜  Python中的命名空间和范围

📅  最后修改于: 2020-01-13 05:10:19             🧑  作者: Mango

什么是命名空间:
命名空间是一个系统,在Python中,每个对象都有唯一的名称。对象可以是变量或方法。Python本身以Python字典的形式维护名称空间。让我们来看一个示例,计算机中的目录文件系统结构。不用说,一个目录可以有多个目录,每个目录中都有一个具有相同名称的文件。但是,只要指定文件的绝对路径,就可以将文件定向到该文件。
 
同样,Python解释器根据名称空间了解在代码中试图指向的确切方法或变量。因此,变量本身的划分几乎没有提供更多信息。在这里,名称可以是任何Python方法或变量,并且空格取决于尝试访问变量或方法的位置。
 
命名空间的类型:
当Python解释器仅在没有用户定义的模块、方法、类等的情况下运行时,始终会存在诸如print(),id()之类的某些函数,它们内置在名称空间中。用户创建模块时,将创建全局名称空间,稍后创建局部函数将创建局部名称空间。内置的命名空间包含全局命名空间,全局命名空间包含局部命名空间,如下图:

 
命名空间的生命周期:
名称空间的生存期取决于对象的范围,如果对象的范围结束,则该命名空间的生存期将结束。因此,不可能从外部名称空间访问内部名称空间的对象。
例:

# var1是全局空间中变量
var1 = 5
def some_func():
    # var2是局部空间变量
    var2 = 6
    def some_inner_func():
        # var3是嵌套的局部空间变量
        var3 = 7

如下图所示,相同的对象名称可以出现在多个名称空间中,因为相同名称之间的隔离由它们的名称空间自动维护。

但是在某些情况下,可能只对更新或处理全局变量感兴趣,如以下示例所示,应该将其显式标记为全局变量,并进行更新或处理。

# Python代码,处理全局变量
count = 5
def some_method():
    global count
    count = count + 1
    print(count)
some_method()

输出:

6

Python中对象的范围:
范围是指可从其中访问特定Python对象的编码区域。因此,不能从代码的任何地方访问任何特定的对象,必须由对象的允许范围访问。
 
范例1:

# Python代码,展示对象的范围
def some_func():
    print("欢迎来到芒果文档")
    print(var)
some_func()

输出:

欢迎来到芒果文档
Traceback (most recent call last):
  File "/home/ab866b415abb0279f2e93037ea5d6de5.py", line 4, in
    some_func()
  File "/home/ab866b415abb0279f2e93037ea5d6de5.py", line 3, in some_func
    print(var)
NameError: name 'var' is not defined

从上面的输出中可以看到,函数some_func()在main的作用域内,而var在main的作用域内不可用。类似地,在内部函数的情况下,外部函数没有内部局部变量的可访问性,内部局部变量对于内部函数而言是本地的,超出了外部函数的范围。让我们以一个例子来详细了解:

# Python代码,用来展示变量范围
def some_func():
    print("在some_func内")
    def some_inner_func():
        var = 10
        print("在inner function内,var的值:",var)
    some_inner_func()
    print("在外部的var的值: ",var)
some_func()

输出:

在some_func内
在inner function内,var的值: 10
Traceback (most recent call last):
  File "/home/1eb47bb3eac2fa36d6bfe5d349dfcb84.py", line 8, in
    some_func()
  File "/home/1eb47bb3eac2fa36d6bfe5d349dfcb84.py", line 7, in some_func
    print("Try printing var from outer function: ",var)
NameError: name 'var' is not defined