命名空间定义了一定范围内变量名和绑定值的对应关系。 命名空间是键值对的集合,变量名和值具有一一对应关系。 范围定义了命名空间中的变量可以发挥作用的范围。
命名空间在解释器中以字典的形式存在,并且作为看得见摸得着的实体存在。 范围是解释器定义的规则,它决定运行时搜索变量的顺序。 这是一种形而上的虚拟调节。
1. 命名空间 1. 概述
A 是 a 从名称到。大多数都是 as 。
命名空间是名称和对象的映射,命名空间是通过(字典)实现的。
命名空间就像计算机上的文件夹。 同一文件夹中的文件不能具有相同的名称,但属于不同文件夹的两个文件可以具有相同的名称。
同样,相同的对象名称可以存在于不同的命名空间中:
2.命名空间的类型
命名空间的类型分为3类,命名空间的类型也反映了命名空间的生命周期。 这三个类别和生命周期描述如下:
1) 内置名称
语言内置名称,例如函数名称abs、char和异常名称等。
生命周期:
对于内置名称组成的命名空间,它在解释器启动时创建,在解释器退出时删除;
2)全局名称(名字)
模块中定义的名称记录了模块的变量,包括函数、类、其他导入的模块、模块级变量和常量。
生命周期:
对于模块来说,它在创建时创建,并在解释器退出时退出;
3)地方名
函数中定义的名称记录了函数的变量,包括函数的参数和本地定义的变量。 (也是在类中定义的)
生命周期:
对于函数的局部来说,它在每次调用函数时创建,并在函数返回时删除。
注意:命名空间的生命周期取决于对象的范围。 如果对象执行完成,则命名空间的生命周期结束。 因此,我们无法从外部命名空间访问内部命名空间的对象。 例如:
# var1 是全局名称
变量1 = 5
定义():
# var2 是本地名称
变量2 = 6
定义():
# var3 是嵌入的本地名称
变量3 = 7
命名空间分类图如下:
3. 命名空间搜索、创建和销毁顺序
3.1 查找变量
如果程序执行时使用了变量hello,那么查找变量的顺序是:
本地命名空间 -> 全局命名空间 -> 内置命名空间
如果按照这个顺序没有找到对应的变量,就会放弃查找并抛出异常:
:名字“你好”不是。
3.2 各命名空间的创建顺序:
解释器启动 -> 创建内置命名空间 -> 加载模块 -> 创建全局命名空间 -> 调用函数 -> 创建本地命名空间
3.3 各命名空间的销毁顺序:
函数调用结束 -> 销毁函数对应的本地命名空间 -> 虚拟机(解释器)退出 -> 销毁全局命名空间 -> 销毁内置命名空间
4.命名空间总结
模块的引入、函数的调用、类的定义都会引入命名空间。 函数中函数的重新定义和类中成员函数的定义都会再次引入局部。
2. 范围 1. 概述
范围是 a 的 a,其中 a 是 。 ” “这里的意思是到一个名字中去查找这个名字。
作用域是程序可以直接访问的命名空间主体的区域。
2.范围类型
范围分为4类,如下:
范围规则的顺序是:L->E->G->B。 如果本地没有找到该变量,则会在本地区域外进行本地搜索(如闭包)。 如果再次找不到,则会全局搜索,然后如果找不到,就去内置中查找,如下图:
3.全局作用域和局部作用域
局部作用域(Local)是脚本中的最内层,包含局部变量,例如函数或方法内部。 闭包函数()的外层函数包含非局部(non-local)和非全局(non-)变量。 全局作用域()是当前脚本的最外层,比如当前模块的全局变量。 示例如下:
= 0 # 全局范围
# 在闭包函数中定义局部作用域
def 外部():
= 1 # 在闭包函数之外的函数中,作用域相对于函数inner()是非局部的
定义内部():
= 2 # 本地范围
上面的例子展示了闭包函数中的全局作用域和函数,以及函数中的局部作用域。 对于函数inner(),outer()中的作用域是非局部的。
4. 内置范围
内置范围(Built-in):包含最终搜索到的内置变量/关键字等
内置作用域是通过一个标准模块named来实现的,但是变量名本身并不放在内置作用域中,所以必须导入这个文件才能使用它。 在.0中,您可以使用以下代码来查看预定义了哪些变量:
目录()
[''、''、''、''、''、''、''、''、''、'或'、''、'或'...]
只有模块()、类(class)和函数(def,)会引入新的作用域。 其他代码块(如if/elif/else/、try/、for/while等)不会引入新的作用域。 范围,也就是说这些语句内定义的变量也可以从外部访问,如下:
name1 = '苏珊'
if chr('SuSan'.(name1)):
=“我来自中国”
别的:
=“我来自美国”
打印()
#输出结果为:
我是苏珊,我来自中国
实例中的变量是在 if 语句块中定义的,但仍然可以从外部访问它们。
如果它是在函数中定义的,那么它就是局部变量,不能从外部访问。 代码中会报错,出现异常:
# 如果变量是在函数内部定义的,则不能从外部访问它。
定义名称():
name2 = '苏珊'
# 程序内部变量调用方法时报错
if('苏珊'.(name2)):
= '我是'+name2 +','+'我来自中国'
别的:
=“我来自美国”
打印()
#运行输出异常
(大多数电话最后):
文件“.py”,第 30 行,位于
if('苏珊'.(name1)):
: 名称 'name2' 不是
从上面的错误信息中我们可以看到name2是未定义的,因为name2是函数names()中的局部变量,只能在函数内部调用。 函数内的局部变量不能被外部调用。
5. 全局变量和局部变量
局部变量只能在声明它们的函数内访问,而全局变量可以在整个程序中访问。 当调用函数时,函数内声明的所有变量名称都将添加到作用域中。 示例如下:
#全局变量和局部变量
Total = 0 # 这是一个全局变量
# 功能说明
def sum(arg1, arg2):
#返回2个参数的总和。”
Total = arg1 + arg2 # 这里的total是一个局部变量。
print("函数中有局部变量:", 总计)
全部的
# 调用sum函数,传入参数的计算结果显示局部变量。
总和(10, 20)
print("函数外还有全局变量:",总计)
#输出结果为:
函数内的局部变量:30
函数外的全局变量:0
6.和关键词
当内部作用域想要修改外部作用域的变量时,可以使用 and 关键字。
变量访问顺序:
当前作用域局部变量->外部作用域变量->外部作用域变量->...->当前模块全局变量->内置变量
6.1 修改全局变量
数量 = 1
def fun1():
# 声明对全局变量的访问
num # 需要使用关键字声明
# 输出全局变量的原始值
打印(数字)
#修改全局变量
数量 = 123
打印(数字)
# 调用函数
乐趣1()
# 输出修改后的全局变量值
打印(数字)
上例的输出结果为:
123
123
6.2 修改嵌套范围
如果要修改嵌套作用域(作用域、外部非全局作用域)内的变量,则需要关键字
# 定义函数
def 外部():
# 定义变量
数量 = 10
#定义嵌套函数
定义内部():
num # 关键字声明,在函数中使用变量
# 修改变量值
数量 = 100
打印(数字)
内()
打印(数字)
外()
上面的例子输出:
100
100
还有一种特殊情况。 以下代码存在语法错误,运行时会报异常:
b = 8
定义测试():
b = b * 10
打印(b)
测试()
#异常信息:
程序执行异常:
(大多数电话最后):
文件“.py”,第 90 行,位于
测试()
文件“.py”,第 88 行,测试中
一个=一个+1
:本地“a”
错误信息是局部作用域引用错误,因为测试函数中的a使用了局部变量,该变量是未定义的,无法修改。 修改a为全局变量,并通过函数参数传递。 程序可以正常执行,输出结果为:
b = 8
定义测试(b):
b = b * 10
打印(b)
测试(b)
程序输出为:
80
另一种解决方案是添加关键字:
b = 8
定义测试():
乙
b = b * 30
打印(b)
测试()
输出是:
240
6.3 和 的区别