文章目录
- 简介
- 命名空间的查找顺序
- 命名空间的生命周期
- 作用域
- 全局变量和局部变量
- 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中,能够引入作用域的只有模块、类、函数等。其余的诸如if/else、try/except、for/while循环等代码不会引入新的作用域,换言之这些代码块中定义的变量在外部也可以访问。
if True:
dtcloud = 'I like dtcloud'
print(dtcloud)
如果将上文中的dtcloud变量定义在函数中,那么在外部就无法访问这个变量:
报错原因是因为该变量为局部变量,只能在函数内部使用。
全局变量和局部变量
在函数内部定义的变量拥有局部作用域,在函数外部定义的变量有全局作用域。上文也有所提及。局部变量只能在函数内部访问,全局变量能够在整个程序中访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:
total = 60 # 这是一个全局变量
# 可写函数说明
def sum( dtcloud1, dtcloud2 ):
#返回2个参数的和."
total = dtcloud1 + dtcloud2 # total在这里是局部变量.
print ("函数内是局部变量 : ", total)
return total
#调用sum函数
sum( 40, 30 )
print ("函数外是全局变量 : ", total)
global 和 nonlocal关键字
如果想要通过内部作用域修改外部作用域的变量的时候,那么需要用到global 和 nonlocal关键字。
下面的案例是是修改全局变量dtcloud:
dtcloud = 1
def fun1():
global dtcloud # 需要使用 global 关键字声明
print(dtcloud)
dtcloud = "dtcloud"
print(dtcloud)
fun1()
print(dtcloud)
如果需要修改嵌套作用域之中的变量,那么需要用到的关键字是nonlocal,如下所示:
def outer():
dtcloud = 10
print(dtcloud)
def inner():
nonlocal dtcloud # nonlocal关键字声明
dtcloud = "dtcloud"
print(dtcloud)
inner()
print(dtcloud)
outer()