文章目录

  • 简介
  • 命名空间的查找顺序
  • 命名空间的生命周期
  • 作用域
  • 全局变量和局部变量
  • global 和 nonlocal关键字


简介

命名空间是用来存储变量名与对象绑定关系的一个区域,python字典可以实现大部分的命名空间。命名空间的使用避免了在项目中出现名字冲突,究其原因,每个命名空间都是独立的,他们之间没有关系。因此虽然同一个命名空间无法重名,但是不同的命名空间允许重名且不会互相影响。
一般有以下几种命名空间:
内置名称:存储python内置的名称,例如函数名、异常名等等。
全局名称:存储模块的变量,其中包括函数、类、导入的模块、变量与常量等等
局部名称:存储函数中的变量,其中包括函数的参数和局部变量。

命名空间的查找顺序

如果需要使用变量‘dtcloud’,那么在python中则会按照如下顺序:局部名称空间→全局名称空间→内置名称空间,来查找这个变量。如果无法找到变量dtcloud,那么就会抛出NameError异常。

命名空间的生命周期

命名空间的生命周期取决于对象的作用域,对象执行完毕,那么该命名空间生命周期结束。也正因为这个原因,外部命名空间无法访问命名空间内部的对象。

# dtcloud1 是全局名称
dtcloud1 = 5
def some_func():
 
    # dtcloud2 是局部名称
    dtcloud2 = 6
    def some_inner_func():
 
        # dtcloud3 是内嵌的局部名称
        dtcloud3 = 7

作用域

它是一段可以直接访问命名空间的正文区域。在python程序中直接访问一个变量,从内到外一次访问所有作用域直到找到为止,如果没找到,和上文例子一样,会报未定义错误。
在Python中,程序变量的作用域决定了程序访问特定变量的权限。python中有以下几种作用域,它们分别是:
L:即local,最内层,比如函数/方法的内部
E:enclosing,包含非局部也非全局的变量,比如在函数A中包含函数B,对于B中的名称在A的作用域就是非局部。
G:global,当前脚本中最外层的变量,比如当前模块中的全局变量。
B:built-in,包含内部的变量以及关键字,它会在最后才被搜索。
上面的介绍顺序即作用域的搜索顺序。

g_dtcloud = 0  # 全局作用域
def outer():
    o_dtcloud = 1  # 闭包函数外的函数中
    def inner():
        i_dtcloud = 2  # 局部作用域

内部作用域通过名为builtin模块实现。但是需要开发者自行导入文件才能使用,在python3中,使用下面的代码可以查阅预定义的变量:

import builtins
dir(builtins)

python类命名规则服从 python类命名空间_python类命名规则服从


在Python中,能够引入作用域的只有模块、类、函数等。其余的诸如if/else、try/except、for/while循环等代码不会引入新的作用域,换言之这些代码块中定义的变量在外部也可以访问。

if True:
    dtcloud = 'I like dtcloud'
print(dtcloud)

python类命名规则服从 python类命名空间_开发语言_02


如果将上文中的dtcloud变量定义在函数中,那么在外部就无法访问这个变量:

python类命名规则服从 python类命名空间_开发语言_03


报错原因是因为该变量为局部变量,只能在函数内部使用。

全局变量和局部变量

在函数内部定义的变量拥有局部作用域,在函数外部定义的变量有全局作用域。上文也有所提及。局部变量只能在函数内部访问,全局变量能够在整个程序中访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

total = 60 # 这是一个全局变量
# 可写函数说明
def sum( dtcloud1, dtcloud2 ):
    #返回2个参数的和."
    total = dtcloud1 + dtcloud2 # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)
    return total
 
#调用sum函数
sum( 40, 30 )
print ("函数外是全局变量 : ", total)

python类命名规则服从 python类命名空间_python类命名规则服从_04

global 和 nonlocal关键字

如果想要通过内部作用域修改外部作用域的变量的时候,那么需要用到global 和 nonlocal关键字。
下面的案例是是修改全局变量dtcloud:

dtcloud = 1
def fun1():
    global dtcloud  # 需要使用 global 关键字声明
    print(dtcloud) 
    dtcloud = "dtcloud"
    print(dtcloud)
fun1()
print(dtcloud)

python类命名规则服从 python类命名空间_学习_05


如果需要修改嵌套作用域之中的变量,那么需要用到的关键字是nonlocal,如下所示:

def outer():
    dtcloud = 10
    print(dtcloud)
    def inner():
        nonlocal dtcloud   # nonlocal关键字声明
        dtcloud = "dtcloud"
        print(dtcloud)
    inner()
    print(dtcloud)
outer()

python类命名规则服从 python类命名空间_学习_06