命名空间
什么是命名空间?
A namespace is a mapping from names to objects. Most namespaces are currently implemented as Python dictionaries.
命名空间(Namespace)实际上就是一个名称到对象的映射,Python 中命名空间以内置字典形式实现。使用命名空间具有如下好处:
- 便于管理代码:命名空间之间彼此独立,从而避免名称冲突,便于模块化,例如函数
builtins.open
和os.open
可以通过命名空间加以区分。 - 增加代码可读性:通过命名空间可以很容易的指导某个函数在哪一个模块中定义,例如函数
random.seed
和itertools.islice
可以很容易知道它们分别定义在random
和itertools
模块中 。
命名空间分类
Python 中一共有三种命名空间:
- 局部命名空间(Local namespace):包含函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
- 全局命名空间(Global namespace):例如模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
- 内置命名空间(Built-in namespace): Python 语言内置的名称,比如函数名
abs
、char
和异常名称BaseException
、Exception
等等。
命名空间查找顺序
如果在 python 脚本中需要访问变量 foo
,将按照如下顺序依次去各个命名空间中查找:
- 局部命名空间
- 全局命名空间
- 内置命名空间
命名空间生命周期
命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。
作用域
作用域就是一个 Python 程序可以直接访问命名空间的上下文区域。在 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到该变量,否则会报未定义错误。
Python 一共有 4 种作用域,分别是:
- 局部作用域 L(Local):包含局部变量,比如一个函数/方法内部。
- 闭包作用域 E(Enclosing):包含非局部(non-local)和非全局(non-global)的变量,例如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 non-local。
- 全局作用域 G(Global):当前脚本的最外层,比如当前模块的全局变量。
- 内置作用域 B(Built-in):包含了内建的变量/关键字等。
当内部作用域想修改外部作用域的变量时,就要用到 global
和 nonlocal
关键字。