目录
一、命名空间(一)简介 1、命名空间()是名称到对象的映射。 大多数命名空间都是通过字典实现的。 2.命名空间提供了一种避免项目中名称冲突的方法。 3. 每个命名空间都是独立的,没有任何关系,所以一个命名空间不能重名,但不同的命名空间可以重名,没有任何影响。 4. 让我们举一个计算机系统中的例子。 一个文件夹(目录)可以包含多个文件夹。 每个文件夹不能有相同的文件名,但不同文件夹中的文件可以有相同的名称。
(二)命名空间一般有三种 1.内置名称(built-in name)
语言内置名称,例如函数名称abs、char和异常名称等。
2. 全局名称(names)
模块中定义的名称记录了模块的变量,包括函数、类、其他导入的模块、模块级变量和常量。
3. 地方名
函数中定义的名称记录了函数的变量,包括函数的参数和本地定义的变量。 (也在类中定义)
(3)命名空间搜索顺序:
假设我们要使用变量,搜索顺序是:本地命名空间 -> 全局命名空间 -> 内置命名空间。
如果找不到变量,它将放弃并引发异常:
NameError: name 'runoob' is not defined。
(4) 命名空间生命周期
命名空间的生命周期取决于对象的范围。 如果对象执行完成,则命名空间的生命周期结束。
因此,我们无法从外部命名空间访问内部命名空间的对象。
如下图所示,同一个对象名可以存在于多个命名空间中。
2. 范围 (1) 简介
1.作用域是程序可以直接访问命名空间的文本区域。
2、程序中,如果直接访问某个变量,会从内到外依次访问所有作用域,直到找到为止,否则会报未定义的错误。
3、在 中,程序的变量在任何位置都不可访问,访问权限取决于变量被赋值的位置。
4、变量的作用域决定了程序的哪一部分可以访问哪个具体的变量名。
(2) 范围有四种: 1. L(Local)
最内层包含局部变量,例如函数/方法内部。
2. E()
包含非局部(non-local)和非全局(non-)变量。 例如,两个嵌套函数,一个函数(或类)A包含一个函数B,那么对于B中的名称,A中的作用域是 。
3.G()
当前脚本的最外层,如当前模块的全局变量。
4.B(内置)
包含内置变量/关键字等,最后搜索。
(3)规则顺序:L –> E –> G –> B。 1、本地找不到就本地查找(比如闭包),再找不到就本地查找会全局搜索它,然后你会在内置中找到它。
例子:
g_count = 0 # 全局作用域 def outer(): o_count = 1 # 闭包函数外的函数中 def inner(): i_count = 2 # 局部作用域
2. 内置作用域是通过一个名为 的标准模块实现的,但变量名本身并没有放入内置作用域中,因此必须导入该文件才能使用它。 3. 在.0中,可以使用以下代码查看预定义了哪些变量:
>>> import builtins >>> dir(builtins)
4.只有模块()、类(class)和函数(def,)会引入新的作用域,其他代码块(如if/elif/else/、try/、for/while等)不会引入新的作用域new作用域,也就是说这些语句中定义的变量也可以被外部访问到,如下代码:
>>> if True: ... msg = 'I am from Runoob' ... >>> msg 'I am from Runoob' >>>
实例中的msg变量是在if语句块中定义的,但仍然可以从外部访问它。
如果 msg 定义在函数中,则它是局部变量,不能从外部访问:
>>> def test(): ... msg_inner = 'I am from Runoob' ... >>> msg_inner Traceback (most recent call last): File "", line 1, in NameError: name 'msg_inner' is not defined >>>
从错误信息来看,它是未定义的,不能使用,因为它是局部变量,只能在函数内部使用。
(四)全局变量和局部变量 1、函数内部定义的变量具有局部作用域,函数外部定义的变量具有全局作用域。 2. 局部变量只能在声明它们的函数内访问,而全局变量可以在整个程序中访问。 3. 调用函数时,函数中声明的所有变量名都会被添加到作用域中。
例子:
上面例子的输出:
函数内是局部变量 : 30 函数外是全局变量 : 0
(5)and关键字 1.当内部作用域想要修改外部作用域的变量时,使用and关键字。 2、下面的例子修改全局变量num:
上面例子的输出:
1 123 123
3.如果要修改嵌套作用域(作用域、外部非全局作用域)内的变量,需要关键字
例子:
上面例子的输出:
100 100
4.还有另一种特殊情况,假设运行以下代码:
执行上述程序时,错误信息如下:
Traceback (most recent call last): File "test.py", line 7, intest() File "test.py", line 5, in test a = a + 1 UnboundLocalError: local variable 'a' referenced before assignment
错误信息是局部作用域引用错误,因为测试函数中的a使用了局部的、未定义的、无法修改的。
修改a为全局变量:
它也可以作为函数参数传递: