Python 命名空间和作用域

 2024-02-11 05:02:53  阅读 0

命名空间定义了一定范围内变量名和绑定值的对应关系。 命名空间是键值对的集合,变量名和值具有一一对应关系。 范围定义了命名空间中的变量可以发挥作用的范围。

命名空间在解释器中以字典的形式存在,并且作为看得见摸得着的实体存在。 范围是解释器定义的规则,它决定运行时搜索变量的顺序。 这是一种形而上的虚拟调节。

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 和 的区别

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码