前言:如果你接触过c/c++/c#/java,那么对于python中的命名空间也是如此,只不过在些许地方存在细微差异,不过倒无伤大雅。

1. 定义

命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 python 字典来实现的。
命名空间提供了在项目中避免名字冲突的一种方法各个命名空间之间相互独立,没有任何关系同一个命名空间中不能有重名的,但不同的命名空间是可以重名而没有任何影响
实际上命名空间和操作系统中的文件系统的思想是类似的,分而治之就比如说,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名


# 我们在全局的命名空间中定义了变量num, 变量赋值num=1后再赋值num=2, 
# 这里实际是新生成一个int值对象2, 再让num指向它,而1被丢弃, 不是改变a的值, 相当于新生成了num.
# 我们通过id()就可以清晰的看出, 两次num的id值确实不同. 
# 先num=1, 再num=2的行为在c/c++中就是变量重定义的行为, 是万万不行的, 但是在python中, 却是合理的.
# 可以这么理解, num一开始指向存储对象1的那块内存空间, 后来它有指向了对象2所指代的那块内存空间.
num =1
print(id(num))
num =2
print(id(num))

print(num)

print('-----------------------')
def test():
    print('Hello')

print(id(test))

def test():
    print('world')
print(id(test))

test()

java 配置nacos 命名空间_命名空间


[Question]:那这样一来,同一个命名空间中不能有重名的这句话究竟该怎么去理解它,我表示怀疑,此处目前留待查证,后续给出相关解释

2. 有什么好处

现在的软件项目都是一个团队协作,共同开发,每个人开发不同的功能,生成不同的python模块。因此,很容易出现同名的变量、函数或者类定义。那么有了命名空间,这个问题很容易就解决了。因为,不同的模块有不同的命名空间,命名空间之间是相互独立的。

3. 三种命名空间

python中存在3中命名空间。

3.1 内置命名空间(built-in names)
  python 内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。

(1) python 解释器内置了很多函数, 不需要使用 import 导入即可直接使用。

# python 程序可以直接使用内置函数max()和abs().
print(max(1,12))
print(abs(-2))

(2) python 提供了一个内置命名空间,用于记录这些内置函数。python 中存在一个特殊的 builtins 模块,它记录了所有的内置函数。

import builtins
print(dir(builtins))  # dir()列出builtins模块中的变量和函数的名称

java 配置nacos 命名空间_python_02

3.2 全局命名空间(global names)
模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。

(1) python 中的内置函数 globals() 返回表示全局命名空间的字典。

# 在全局空间定义类Studnet, 函数test(), 变量s1和s2
class Student:
    def __init__(self, num):
        self.num = num

    def show(self):
        pass


def test():
    pass


s1 = Student(101)
s2 = Student(102)

print(globals())
# 程序输出
# 输出包括了 Student、test、s1和s2, 它们是用户定义的全局函数和变量.
{
	'__name__': '__main__', 
	'__doc__': None, 
	'__package__': None, 
	'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001ADFF046D00>, 
	'__spec__': None,
	'__annotations__': {}, 
	'__builtins__': <module 'builtins' (built-in)>, 
	'__file__': 'F:\\编程系列\\Python\\Python\\_01_Essential\\temp.py', 
	'__cached__': None, 
	'Student': <class '__main__.Student'>, 
	'test': <function test at 0x000001ADFF1DA550>, 
	's1': <__main__.Student object at 0x000001ADFF1E2FD0>, 
	's2': <__main__.Student object at 0x000001ADFF1E2F10>
}

3.3 局部命名空间(local names)
函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)

(1) python 中的内置函数 locals() 返回表示全局命名空间的字典。

# Student类的构造函数中定义两个参数num, name, 以及在test()中定义一个局部变量addr.
# getLocals()中定义2个参数num1, num2, 以及局部变量temp.
class Student:
    def __init__(self, num, name):
        self.num = num
        self.name = name
        print('###########', locals())

    def test(self):
        addr = 'SuZhou'
        print('@@@@@@@@@@', locals())


def getLocals(num1, num2):
    temp = 2
    str = "HelloWorld"
    return locals()


if __name__ == "__main__":
    print(getLocals(1, 2))
    print('-----------------------------')
    Student(101, 'Zhang').test()

java 配置nacos 命名空间_java 配置nacos 命名空间_03

4. 命名空间的查找顺序

假设我们要使用变量 temp,则 python 的查找顺序为:局部的命名空间 -> 全局命名空间 -> 内置命名空间
如果找不到变量 temp,它将放弃查找并引发一个 NameError 异常。
(1) 在局部命名空间中,查找变量;
(2) 如果找不到,则在全局命名空间中,查找变量;
(3) 如果找不到,则在内置命名空间中,查找变量;
(4) 如果找不到,则抛出 NameError 异常。

# 示例性代码
tel = 101
name = 'Zhang'

def test(num1, num2):
    temp1 = 12
    temp2 = 24
    # 在此处访问某个变量
    '''
    内置命名空间, 包括: max、min、abs 等内置函数
    全局命名空间, 包括:tel, name, test()
    局部命名空间, 包括:num1, num2, temp1, temp2
    '''
    '''
    如果访问的变量是num1, 则能在局部命名空间中找到; 
    如果访问的变量是tel, 则能在全局命名空间中找到; 
    如果访问的变量是max,则能在内置命名空间中找到; 
    如果访问的变量是 x,在以上三个命名空间中查找不到, 此时抛出异常 NameError.
    '''

test()

5. 命名空间的生命周期

命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。