一、命名空间
名称(命名)空间是从名称到对象的映射。目前,大多数名称空间都实现为Python字典
三种命名空间
内置名称(built-in names)
Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
全局名称(global names)
模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
局部名称(local names)
函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
命名空间查找顺序:
局部 -> 全局 -> 内置
命名空间的生命周期:
命名空间的生命周期取决于对象的作用域,如果对象执行完成则该命名空间的生命周期就结束。
简而言之,我们在方法内定义的变量等,当方法执行结束就会消失,相当于一次性使用,下次再使用则重新创建一个临时的变量。
二、作用域
作用域是Python程序的一个文本区域,其中可以直接访问命名空间。这里的“可直接访问”意味着对名称的非限定引用试图在命名空间中查找该名称。
四种作用域:
L(Local):
最内层,包含局部变量,比如一个函数/方法内部。
E(Enclosing):
包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
G(Global):
当前脚本的最外层,比如当前模块的全局变量。
B(Built-in):
包含了内建的变量/关键字等,最后被搜索。
顺序: L –> E –> G –> B。
局部找不到时会去局部外的局部找(例如闭包),再找不到就会去全局找,还不行就去内置中找。
a = 1 # 全局作用域
def def1():
b = 2 # 闭包函数外的函数中
def def2():
c = 3 # 局部作用域
简单说,函数内部定义的变量,外部是没法直接用的,但外部的变量可以传递到某一函数内以供使用,或通过特殊的关键字直接引用外部的变量
三、global 和 nonlocal
当想从内部作用域访问或修改外部作用域的变量时,就可以使用 global 和 nonlocal 关键字完成这个动作
例如:
a = 1
def def1():
global a # global 关键字声明
print(a)
例如
def def1():
num = 1
def def2():
nonlocal num # nonlocal关键字声明
num = 2